WerteTabelle
Betriebsstunden | Verbrauch |
1 | 1,8 |
2 | 4,6 |
3 | 6,8 |
4 | 7,7 |
5 | 9,0 |
6 | 12,3 |
7 | 14,8 |
8 | 15,9 |
Unser Interesse gilt der Berechnung des Verbrauchs pro Stunde. Dazu muss man nur jeweils die Differenz aller Verbrauchswerte berechnen.
Betriebsstunden | Verbrauch | Minus | Verbrauch Zeile vorher | ist | Verbrauch pro Stunde |
1 | 1,8 | - | 0,0 | = | 1,8 |
2 | 4,6 | - | 1,8 | = | 2,8 |
3 | 6,8 | - | 4,6 | = | 2,2 |
5 | 7,7 | - | 6,8 | = | 0,9 |
6 | 9,0 | - | 7,7 | = | 1,3 |
7 | 12,3 | - | 9,0 | = | 3,3 |
8 | 14,8 | - | 12,3 | = | 2,5 |
9 | 15,9 | - | 14,8 | = | 1,1 |
Wie mach man das mit SQL? Mein erster "Reflex" einer Lösung ging über ein CURSOR in einer Stored Procedure. Dies klappt natürlich auch. Besinnt man sich aber darauf, dass SQL eine Mengenabfragesprache ist, so kann man eine elegantere Lösung finden. Wir haben zwei Mengen. Unserer Ausgangstabelle und die Menge der Ausgangstabelle um eine Zeile verschoben. Wir JOINen beide Mengen und subtrahieren die Verbrauchswerte.
Wie aber nun einen JOIN auf die Zeile vorher machen?
Seit SQL 2005 gibt es die TSQL Funktion ROW_NUMBER(). Sie gibt als Integer die Nummer der Zeile zurück. Wir können den erforderlichen JOIN auf die Zeile vorher durchführen, indem wir in der zweiten Menge die ROW_Number minus 1 zurückgeben:
Menge von Spalte Verbrauch mit ROW_Number | Menge von Spalte Verbrauch mit ROW_Number minus 1 | ||||||||||||||||||||||||||||||||||||
|
|
Mit ROW_NUMBER und ROW_NUMBER minus 1 erhält man die zwei Mengen für der JOIN auf die vorherige Spalte:
Verbrauch | ROW_NUMBER | ROW_NUMBER - 1 | Verbrauch |
0 | 1,8 | ||
1,8 | 1 | 1 | 4,6 |
4,6 | 2 | 2 | 6,8 |
6,8 | 3 | 3 | 7,7 |
7,7 | 4 | 4 | 9,0 |
9,0 | 5 | 5 | 12,3 |
12,3 | 6 | 6 | 14,8 |
14,8 | 7 | 7 | 15,9 |
15,9 | 8 |
Mit einer CTE können wir nun das Ergebnis gleich in einem Rutsch ausgeben:
1: WITH WerteTabelle(Betriebsstunden, Verbrauch)
2: AS
3: (
4: SELECT Betriebsstunden = 1, Verbrauch = 1.8 UNION
5: SELECT Betriebsstunden = 2, Verbrauch = 4.6 UNION
6: SELECT Betriebsstunden = 3, Verbrauch = 6.8 UNION
7: SELECT Betriebsstunden = 4, Verbrauch = 7.7 UNION
8: SELECT Betriebsstunden = 5, Verbrauch = 9.0 UNION
9: SELECT Betriebsstunden = 6, Verbrauch = 12.3 UNION
10: SELECT Betriebsstunden = 7, Verbrauch = 14.8 UNION
11: SELECT Betriebsstunden = 8, Verbrauch = 15.9
12: )
13: ,Menge1(Nr, Betriebsstunden, Verbrauch)
14: AS
15: (
16: SELECT
17: ROW_NUMBER() OVER (ORDER BY Betriebsstunden) AS 'Nr',
18: Betriebsstunden,
19: Verbrauch
20: FROM WerteTabelle
21: )
22: ,Menge2(NrMinusEins, Betriebsstunden, Verbrauch)
23: AS
24: (
25: SELECT
26: (ROW_NUMBER() OVER (ORDER BY Betriebsstunden) - 1) AS 'NrMinusEins',
27: Betriebsstunden,
28: Verbrauch
29: FROM WerteTabelle
30: )
31:
32: SELECT
33: Menge1.Betriebsstunden,
34: Menge1.Verbrauch,
35: Menge2.Verbrauch AS 'Verbrauch Zeile Vorher',
36: Menge2.Verbrauch - Menge1.Verbrauch AS 'Verbrauch pro Stunde'
37: FROM
38: Menge1
39: INNER JOIN Menge2 ON Menge1.Nr = Menge2.NrMinusEins
40:
Ergebnis:
0 Kommentare:
Kommentar veröffentlichen