Supponendo di avere una colonna ordinamento - dice id
- allora si può fare quanto segue in SQL Server 2012:
select col,
col - coalesce(lag(col) over (order by id), 0) as diff
from t;
Nelle versioni precedenti di SQL Server, si può fare quasi la stessa cosa con un subquery correlata:
select col,
col - isnull((select top 1 col
from t t2
where t2.id < t.id
order by id desc
), 0)
from t
Questo utilizza isnull()
invece di coalesce()
a causa di un "bug" in SQL Server che valuta il primo argomento due volte quando si utilizza coalesce()
.
Si può anche fare questo con row_number()
:
with cte as (
select col, row_number() over (order by id) as seqnum
from t
)
select t.col, t.col - coalesce(tprev.col, 0) as diff
from cte t left outer join
cte tprev
on t.seqnum = tprev.seqnum + 1;
Tutti questi supporre che avete un po 'di colonna per specificare l'ordinamento. Potrebbe essere un id
, una data di creazione o qualcos'altro. Le tabelle SQL sono intrinsecamente non ordinate, quindi non esiste una "riga precedente" senza una colonna che specifica l'ordine.
fonte
2013-07-10 01:16:13
Tenete a mente non c'è alcuna cosa come "riga precedente" in un risultato SQL imposta a meno che non si utilizza un "ORDER BY" clausola per definire l'ordine. Inoltre, dovresti provare a pensare in termini di set con database relazionali, quindi spero che qualcuno ti dia una risposta settata (devo andarmene ora). –
., Sì. Ma come posso definirlo in ordine per clausola? Grazie ... – Nemesis
Struttura (scusate devo eseguire): definire un CTE che utilizza ORDER BY per scegliere un ordine e quindi utilizza [ROW_NUMBER] (http : //technet.microsoft.com/en-us/library/ms186734.aspx) per aggiungere una colonna che definisce l'ordine. Quindi unire il CTE a se stesso su x.ROWNUM = y.ROWNUM + 1 e includere x.value-y.value. –