Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Durchschnittswert von bestimmten mehrfach vorhandenen Datensätzen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Dominik85, 2 Februar 2016.

  1. Dominik85

    Dominik85 Benutzer

    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:

    Zuletzt bearbeitet: 2 Februar 2016
  2. ukulele

    ukulele Datenbank-Guru

    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.
     
  3. Dominik85

    Dominik85 Benutzer

    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! ;)
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden