none
TSQL: Für jeden Datensatz einen Wert des Vorgängers suchen RRS feed

  • Frage

  • Hallo miteinander,

    ich habe eine Frage, für die es möglicherweise eine elegante Lösung gibt, die ich aber leider nicht kenne oder selbst darauf komme.

    Ich habe eine Tabelle, die ich nicht verändern kann. Es wird die Anzahl der produzierten Stück einer Maschine gezählt und immer der kumulierte Wert in der Datenbank gespeichert. Mir fehlt die Differenz zum letzten Datensatz, dh. die Anzahl der Stück, die hinzugekommen sind. Hier ist die Tabelle vereinfacht, der Zeitstempel ist die Minute des Tages, also 7:00 Uhr = 420, gefolgt von der gezählten Menge:

    Zeitstempel;kumulierteMenge

    400;0
    404;25
    409;60
    413;85
    420;121
    usw.

    Das Ergebnis einer Abfrage od. Prozedur sollte sein:

    Zeitstempel;kumulierteMenge;DifferenzMenge

    400;0;0
    404;25;25
    409;60;35
    413;85;25
    420;121;36
    usw.

    Wie geht man so etwas an? Ich hoffe, ich konnte mich verständlich ausdrücken.

    lg
    arno

    Freitag, 11. September 2015 08:25

Antworten

  • Hi,

    damit sollte es funktionieren: (#TEMP ist in meinem Beispiel dein Tabellenname)

    WITH TEMPTABLE AS (
    		SELECT ROW_NUMBER() OVER (
    				ORDER BY ZEITSTEMPEL
    				) AS ID
    			,ZEITSTEMPEL
    			,KUMULIERTEMENGE
    		FROM #TEMP
    		)
    
    SELECT ZEITSTEMPEL
    	,KUMULIERTEMENGE
    	,KUMULIERTEMENGE - ISNULL((
    			SELECT KUMULIERTEMENGE
    			FROM TEMPTABLE T2
    			WHERE T2.ID = T1.ID - 1
    			), 0) AS DIFF
    FROM TEMPTABLE T1

    Ansonsten kannst du auch mal hier schauen:

    https://msdn.microsoft.com/de-de/library/ms189461(v=SQL.120).aspx

    Grüße

    Olli


    • Bearbeitet Oliver Rzeniecki Freitag, 11. September 2015 08:55 Etwas vergessen :-)
    • Als Antwort markiert cavallino Montag, 14. September 2015 07:02
    Freitag, 11. September 2015 08:54

Alle Antworten

  • Hi,

    damit sollte es funktionieren: (#TEMP ist in meinem Beispiel dein Tabellenname)

    WITH TEMPTABLE AS (
    		SELECT ROW_NUMBER() OVER (
    				ORDER BY ZEITSTEMPEL
    				) AS ID
    			,ZEITSTEMPEL
    			,KUMULIERTEMENGE
    		FROM #TEMP
    		)
    
    SELECT ZEITSTEMPEL
    	,KUMULIERTEMENGE
    	,KUMULIERTEMENGE - ISNULL((
    			SELECT KUMULIERTEMENGE
    			FROM TEMPTABLE T2
    			WHERE T2.ID = T1.ID - 1
    			), 0) AS DIFF
    FROM TEMPTABLE T1

    Ansonsten kannst du auch mal hier schauen:

    https://msdn.microsoft.com/de-de/library/ms189461(v=SQL.120).aspx

    Grüße

    Olli


    • Bearbeitet Oliver Rzeniecki Freitag, 11. September 2015 08:55 Etwas vergessen :-)
    • Als Antwort markiert cavallino Montag, 14. September 2015 07:02
    Freitag, 11. September 2015 08:54
  • Vielen Dank Olli,

    das funktioniert perfekt! PS: SQL-Server 2008 R2

    lg

    Arno


    • Bearbeitet cavallino Dienstag, 15. September 2015 07:43
    Montag, 14. September 2015 07:07
  • Mit den Window Functions kann man sehr elegant auf den Vorgänger zugreifen oder auf den Nachfolger (LEAD).

    Declare @Daten as Table(Zeitstempel int, kumulierteMenge int);
     Insert into @Daten(Zeitstempel, kumulierteMenge) values (400, 0);
    Insert into @Daten(Zeitstempel, kumulierteMenge) values (404, 25);
    Insert into @Daten(Zeitstempel, kumulierteMenge) values (409, 60);
    Insert into @Daten(Zeitstempel, kumulierteMenge) values (413, 85);
    Insert into @Daten(Zeitstempel, kumulierteMenge) values (420, 121);
    
    Select Zeitstempel, kumulierteMenge, coalesce(kumulierteMenge -
    LAG(kumulierteMenge) OVER(ORDER BY Zeitstempel), 0) as DifferenzMenge
    from @Daten;

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Dienstag, 15. September 2015 06:52
    Beantworter
  • Hallo Christoph,

    danke für die Antwort! LAG/LEAD funktionieren meiner Meinung nach erst ab SQL Server 2012, ich habe aber nur Version 2008 R2 und bekomme daher Fehlermeldungen ('lag' is not a recognized built-in function name.).

    lg

    arno

    Dienstag, 15. September 2015 07:42
  • Das stimmt natürlich, aber davon stand ja auch in der Frage nichts. Aber ich dachte, falls andere mal diesen Thread finden, sollen sie aber zumindest eine Lösung auf dem jetzt (2015) aktuellen Sprachumfang finden.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Dienstag, 15. September 2015 09:41
    Beantworter