Willkommen bei Entwickler-Forum.
Ergebnis 1 bis 6 von 6
  1. #1
    Zaungast
    Registriert seit
    21.10.2011
    Beiträge
    34

    Standard Datensätze mit Datum zusammenfügen

    Hallo,

    ich habe ein weiteres Datums-Abfrage-Problem:
    PersonID Von Bis
    1 01.01.16 05.01.16
    1 06.01.16 20.01.16
    1 25.01.16 03.02.16

    und als Ergebnis der Abfrage hätte ich nun gerne:
    PersonID Von Bis
    1 01.01.16 20.01.16
    1 25.01.16 03.02.16

    Also, direkt aufeinander folgende Daten sollen zu einem Satz erzeugt werden.
    Geht das mit Lag und Lead?

    Vielen Dank!

  2. #2
    Stammgast
    Registriert seit
    26.02.2003
    Beiträge
    4.803

    Standard

    Um da die richtige Abfrage zu finden brauchst du eine bessere Problemdefinition.

    - Was ist wenn mehr als 2 Zeiträume zusammenhängen (als z.B. 01.01.-05.01. , 06.01.-20.01, 21.01-31.01.) soll dann auch 1 Zeitraum draus werden oder 2 sich überschneidende die jeweils den mittleren Zeitraum enthalten.
    - Was ist wenn noch mehr zusammenhängende Zeiträume existieren?
    - Was ist wenn 2 Zeiträume sich überschneiden?
    - Was ist wenn ein Zeitraum komplett in einen anderen liegt.
    - Was ist wenn ein Zeitraum in einem anderen zusammenhängenden Zeitraum liegt (01.01.-05.01., 06.01-20.01. und dann noch 03.01.-18-01)
    - Gibt es weitere Sonderfälle die wir nicht erkennen können. (Zum Beispiel sowas wie 01.01-09.01. und 12.01.31.01. sind auch zusammenhängend weil der 10.01, 11.01 ein Wochenende waren)

    Lag und Lead wird dir vermutlich nicht helfen. Wir sind, je nachdem was du noch für Bedingungen hast eher im Bereich (rekursive) CTE oder Stored Function/Procedure weil sich das so einfach als simples SQL nicht ausdrücken lässt.

  3. #3
    Zaungast
    Registriert seit
    21.10.2011
    Beiträge
    34

    Standard

    - Was ist wenn mehr als 2 Zeiträume zusammenhängen (als z.B. 01.01.-05.01. , 06.01.-20.01, 21.01-31.01.) soll dann auch 1 Zeitraum draus werden oder 2 sich überschneidende die jeweils den mittleren Zeitraum enthalten.
    Es sollen generell alle Zeiträume aneinander gehängt werden, die unmittelbar aufeinander folgen, so dass es zu einem Zeitraum wird.

    - Was ist wenn noch mehr zusammenhängende Zeiträume existieren?
    s.o.

    - Was ist wenn 2 Zeiträume sich überschneiden?
    das kommt nicht vor, falls durch einen Fehler doch, dann das früheste Anfangs- und späteste Enddatum

    - Was ist wenn ein Zeitraum komplett in einen anderen liegt.
    dann auch das früheste Anfangs- und späteste Endedatum

    - Was ist wenn ein Zeitraum in einem anderen zusammenhängenden Zeitraum liegt (01.01.-05.01., 06.01-20.01. und dann noch 03.01.-18-01)
    dann auch das früheste Anfangs- und späteste Endedatum

    - Gibt es weitere Sonderfälle die wir nicht erkennen können. (Zum Beispiel sowas wie 01.01-09.01. und 12.01.31.01. sind auch zusammenhängend weil der 10.01, 11.01 ein Wochenende waren)
    Um was für einen Tag es sich handelt ist irrelevant, es sollen lediglich mehrere aneinanderhängende Zeiträume zu einem zusammengefasst werden.

    Was ist CTE? das kenne ich nicht. Unter Oracle hätte ich das mit pl/sql gemacht, wie macht man das in mssql?

    Vielen Dank!

  4. #4
    Stammgast
    Registriert seit
    24.10.2011
    Beiträge
    1.261

    Standard

    Zitat Zitat von Chriss Beitrag anzeigen
    Was ist CTE? das kenne ich nicht. Unter Oracle hätte ich das mit pl/sql gemacht, wie macht man das in mssql?
    Common Table Expressions
    https://en.wikipedia.org/wiki/Common_table_expression

    Auch wen es am Ende wohl komplexer wird, hier mal ein Ansatz:
    Code:
    select pv.*, pb.bis from person pv , person pb
     where pv.bis +1 = pb.von
    Gruß, defo

  5. #5
    Stammgast
    Registriert seit
    26.02.2003
    Beiträge
    4.803

    Standard

    Ne einfache Lösung geht mir gerade ab.

    Das hier funktioniert zumindest in dem von dir beschriebenen Fall ohne (fehlerhafte) Überschneidungen. Ist aber komplizierter als ich erhofft/vermutet habe

    Code SQL:
    WITH rec AS 
    (SELECT A.PersonID, A.DatumVon, A.DatumBis, DATEDIFF(dd, A.DatumVon, A.DatumBis) AS Days
       FROM Anwesenheit A
      UNION ALL
     SELECT A1.PersonID, A1.DatumVon, A2.DatumBis, DATEDIFF(dd, A1.DatumVon, A2.DatumBis) AS Days
       FROM rec A1
              INNER JOIN Anwesenheit A2 ON A1.DatumBis = DATEADD(dd, -1, A2.DatumVon) AND A1.PersonID = A2.PersonID   
    ) 
     
    SELECT PersonID, DATEADD(dd, -Days, DatumBis) AS DatumVon, DatumBis
      FROM (SELECT PersonID, DatumBis, MAX(Days) AS Days
              FROM (SELECT PersonID, DatumVon, DATEADD(dd, Days, DatumVon) AS DatumBis, DATEDIFF(dd, DatumVon, DATEADD(dd, Days, DatumVon)) AS Days
                      FROM (SELECT PersonID, DatumVon, MAX(Days) AS Days
                              FROM rec
                             GROUP BY PersonID, DatumVon) A) A2
     GROUP BY PersonID, DatumBis) A3 
     ORDER BY PersonID, DATEADD(dd, -Days, DatumBis)
    Geändert von Ralf Jansen (24.11.2015 um 10:30 Uhr) Grund: Link korrigiert und sicherheitshalber SQL angehängt

  6. #6
    Stammgast
    Registriert seit
    24.10.2011
    Beiträge
    1.261

    Standard

    Ja, scheint ein nicht triviales Problem zu sein. Mein Ansatz zur Päärchenfindung zeigt ja eigentlich auch nur, dass es recursiv ist.

    Der Link von Ralph ist etwas kaputt, aber zur Lösung dahinter:

    Eine recursive CTE in der Form zu verwenden sieht nach MSSQL aus, erinnert mich aber an Oracle "connect by prior".
    lag und lead erinnert mich ebenfalls an Oracle.
    Geht es hier um Oracle oder MS SQL oder noch was anderes?
    Und welche Version?
    Gruß, defo

 

 

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •