2016-03-31 12 views
3

Ich versuche, eine Abfrage zu schreiben, die den Unterschied zwischen den Wert Zeilen als eine neue Spalte namens Differenz berechnet, wenn das Datetime-Feld in aufsteigender Reihenfolge ist.Unterschied zwischen zwei Zeilen mit Datum in aufsteigender Reihenfolge

Zum Beispiel sollte 2016.03.02 seine 102.340.624 - 102269208

select datetime, tagname, value 
from runtime.dbo.AnalogHistory 
where datetime between '20160301 00:00' and '20160401 00:00' 
and TagName = 'EWS_A3_PQM.3P_REAL_U' 
and wwResolution = (1440 * 60000) 
order by DateTime asc 

DATETIME     TAGNAME     VALUE  DIFFERENCE 
2016-03-01 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102269208 
2016-03-02 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102340624 
2016-03-03 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102411568 
2016-03-04 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102478104 
2016-03-05 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102549088 
2016-03-06 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102612592 
2016-03-07 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102682984 
2016-03-08 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102747000 
2016-03-09 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102817176 
2016-03-10 00:00:00.0000000 EWS_A3_PQM.3P_REAL_U 102887896 

Vielen Dank im Voraus

+2

, wenn Sie SQL Server 2012 verwenden, können Sie LEAD(), LAG() Fensterfunktion – Squirrel

+2

verwenden Wenn Sie SQL Server 2008 verwenden Sie es mit ROW_NUMBER mit Selbstverbindungs ​​ – cha

Antwort

2

Sie können die Verzögerungsfunktion verwenden, um den vorherigen Zeilen Wert zu erhalten.

Select datetime, tagname, value, value- coalesce(lag(value) over(partition by tagname order by datetime),0) [difference] 
from runtime.dbo.AnalogHistory 
where datetime between '20160301 00:00' and '20160401 00:00' 
and TagName = 'EWS_A3_PQM.3P_REAL_U' 
and wwResolution = (1440 * 60000) 
order by DateTime asc 
0

für SQL Server-Versionen 2005 oder höher, aber vor 2012 (wo Sie haben keine Verzögerung und Blei Funktionen)

;with cte as 
(
    select datetime, tagname, value 
    from runtime.dbo.AnalogHistory 
    where datetime between '20160301 00:00' and '20160401 00:00' 
    and TagName = 'EWS_A3_PQM.3P_REAL_U' 
    and wwResolution = (1440 * 60000) 
) 

select datetime, tagname, value, value - isnull((select top 1 value from cte t2 where t2.datetime < t1.datetime order by t2.datetime desc), 0) as difference 
from cte t1 
order by DateTime 

für SQL Server 2012 oder höher:

select datetime, tagname, value, value - isnull(lag(value) over (order by datetime), 0) 
from runtime.dbo.AnalogHistory 
where datetime between '20160301 00:00' and '20160401 00:00' 
and TagName = 'EWS_A3_PQM.3P_REAL_U' 
and wwResolution = (1440 * 60000) 
order by DateTime 
+0

Je in der Größe der Tabelle erreichen können Es könnte besser sein, einen Rang auf der Cte hinzuzufügen und dann die Cte ​​auf sich selbst zu tun, statt eine Top 1 zu tun wählen –

+0

@WyattShipman korrekte, Rang oder Zeilennummer könnte mit einer besseren Leistung in großen Tabellen führen. –

0

Dies funktioniert für jede Version. Alles, was Sie tun müssen, ist +1 zu Ihrem Datum hinzufügen, um die nächste Spalte zu erhalten, für die letzte Spalte, Sie werden obviosuly nicht nächsten Wert haben, können Sie verwenden, ist Null-Funktion zum Anpassen ..

select 
t1.*,isnull(b.difference ,t1.value) as difference from yourtable t1 
outer apply 
(
select (t2.value-t1.value) as difference from yourtable t2 
where dateadd(day,1,t1.date)=t2.date 
) b 
Verwandte Themen