Durchschnittswert von bestimmten mehrfach vorhandenen Datensätzen

Dominik85

Benutzer
Beiträge
5
Guten Morgen,

ich möchte die Summe aus der Zeitdifferenz von bestimmten Datensätzen ermitteln, schaffe das aber leider nicht.
Ein Beispiel der Tabelle ist angehängt.
Die Lfd. Nr. wird nach Datum/Uhrzeit vergeben, es kann somit zwar danach sortiert werden, allerdings sind die Nummern innerhalb eines Beleges oftmals nicht fortlaufend. Wichtig ist für mich aber die Gruppierung nach "Beleg".
Es geht nun darum, pro Beleg alle Zeitdifferenzen zu ermitteln, in denen der Status "32" aktiv gesetzt war.
Also zB:
A002:
Lfd. Nr. 22 bis Lfd. Nr. 23 (4 Minuten)
Lfd. Nr. 29 bis Lfd. Nr. 30 (40 Minuten)

D.h. das erwünschte Ergebnis wäre "44 Minuten".
MS SQL Server 2012 ist im Einsatz.

Vielen Dank für eure Vorschläge!
 

Anhänge

  • bsp log.jpg
    bsp log.jpg
    105,6 KB · Aufrufe: 15
Zuletzt bearbeitet:
Werbung:
Ist fast ganz einfach :)
Code:
--Testdaten erzeugen
WITH tabelle(lfd_nr,beleg,status_davor,status_danach,datum,zeit) AS (
SELECT    22,'A002',30,32,cast('2016-01-08' AS DATE),cast('11:38' AS TIME)
UNION ALL
SELECT    23,'A002',32,30,cast('2016-01-08' AS DATE),cast('11:42' AS TIME)
UNION ALL
SELECT    29,'A002',30,32,cast('2016-01-08' AS DATE),cast('17:30' AS TIME)
UNION ALL
SELECT    30,'A002',32,30,cast('2016-01-08' AS DATE),cast('18:10' AS TIME)
        )
-- Ende Testdaten
SELECT    t1.beleg,
        sum(datediff(mi,
        cast(t1.datum AS DATETIME) + cast(t1.zeit AS DATETIME),
        cast(t2.datum AS DATETIME) + cast(t2.zeit AS DATETIME))) AS Zeit
FROM    (

SELECT    ROW_NUMBER() OVER (PARTITION BY beleg ORDER BY lfd_nr) AS zeile,
        *
FROM    tabelle
WHERE    status_davor = 30
AND        status_danach = 32
OR        status_davor = 32
AND        status_danach = 30

        ) t1
INNER JOIN (

SELECT    ROW_NUMBER() OVER (PARTITION BY beleg ORDER BY lfd_nr) AS zeile,
        *
FROM    tabelle
WHERE    status_davor = 30
AND        status_danach = 32
OR        status_davor = 32
AND        status_danach = 30

        ) t2
ON        t1.beleg = t2.beleg
AND        t1.zeile + 1 = t2.zeile
AND        t1.status_davor = 30
AND        t1.status_danach = 32
AND        t2.status_davor = 32
AND        t2.status_danach = 30
GROUP BY t1.beleg
Oben das WITH tabelle() erstellt mir nur eine Tabelle mit Testdaten, da kannst du statt dessen deine eigene Tabelle nehmen.

Über ROW_NUMBER() erzeuge ich eine Sortierung. Hier sollte man natürlich nicht mit * arbeiten und da ich das ganze mit sich selbst joine macht es Sinn, diesen Schritt in eine Sicht auszulagern.

Deine Unterscheidung in DATE und TIME als Spalten ist eher hinderlich, vieleicht arbeitest du gleich mit DATETIME wenn das noch möglich ist.

Deine Daten sind stark von Vollständigkeit abhängig und davon, das immer Status 30->32 und 32->30 in der korrekten Reihenfolge kommen. Wenn es auch wechsel auf andere Nummern geben kann dann müsste man diese starre Prüfung aufweichen oder entfernen.
 
Werbung:
Vielen Dank!!!
Habe jetzt noch alle Abfragen bez. "30" entfernt, da es eben auch sein kann, dass vor "32" oder nach "32" irgendein anderer Code steht - und soweit ich gesehen habe, funktioniert das einwandfrei! ;)
 
Zurück
Oben