Announcement

Collapse
No announcement yet.

Zeiträume kummulieren?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zeiträume kummulieren?

    Hallo Zusammen,

    ich komme gerade nicht weiter und hoffe, dass Ihr mir helfen könnt.

    Ich habe folgende Daten

    [highlight=sql]
    with data as
    (select '1' as id,TO_DATE('01.01.2010') as VON_1,TO_DATE('30.04.2010') as BIS_1,TO_DATE('01.01.2010') as VON_2,
    TO_DATE('31.05.2010') as BIS_2 from DUAL union all
    select '1',TO_DATE('01.05.2010'),TO_DATE('01.01.9999'),TO _DATE('01.06.2010'),TO_DATE('01.01.9999') from DUAL union all
    select '2',TO_DATE('01.01.2005'),TO_DATE('01.01.2009'),TO _DATE('01.01.2005'),TO_DATE('01.01.2009') from DUAL union all
    select '2',TO_DATE('05.01.2009'),TO_DATE('30.04.2010'),TO _DATE('05.01.2009'),TO_DATE('30.04.2010') from DUAL union all
    select '3',TO_DATE('01.01.2010'),TO_DATE('30.04.2010'),TO _DATE('30.04.2010'),TO_DATE('30.04.2010') from DUAL union all
    select '3',TO_DATE('30.04.2009'),TO_DATE('30.04.2010'),TO _DATE('01.05.2010'),TO_DATE('30.04.2010') from DUAL union all
    select '3',TO_DATE('01.05.2010'),TO_DATE('01.10.2010'),TO _DATE('02.05.2010'),TO_DATE('01.10.2010') from DUAL union all
    select '3',TO_DATE('02.10.2010'),TO_DATE('01.10.2011'),TO _DATE('02.05.2010'),TO_DATE('01.01.9999') from DUAL union all
    select '3',TO_DATE('02.10.2011'),TO_DATE('01.01.9999'),TO _DATE('02.05.2010'),TO_DATE('01.01.9999') from DUAL union all
    select '4',TO_DATE('01.01.2010'),TO_DATE('01.10.2011'),TO _DATE('01.01.2010'),TO_DATE('01.10.2011') from DUAL union all
    select '4',TO_DATE('02.12.2011'),TO_DATE('13.05.2011'),TO _DATE('02.05.2010'),TO_DATE('01.10.2011') from DUAL union all
    select '4',TO_DATE('13.05.2011'),TO_DATE('01.01.9999'),TO _DATE('01.10.2011'),TO_DATE('01.01.9999') from DUAL)select * from data;
    [/highlight]

    Ich muss herrausfinden, bei wem die Zeiträume, kummuliert über die ID durchgehen sind.
    Für diesen Fall benötige ich einen DS mit dem minimum des von und des maximums des bis.

    Bsp
    4 01.01.2010 01.01.9999

    Falls nicht durchgehend, jeden einzelnen Zeitraum

    Bsp
    2 01.01.2005 01.01.2009 01.01.2005 01.01.2009
    2 05.01.2009 30.04.2010 05.01.2009 30.04.2010

    Und dies für beide Datumspaare, also von_1/bis_1 sowie von_2/bis_2


    Vielen Dank im voraus


    Vielöe Grüße

    Martin

  • #2
    Warum gibt es denn pro Zeile immer 2 VON BIS?

    Comment


    • #3
      Originally posted by fanderlf View Post
      Warum gibt es denn pro Zeile immer 2 VON BIS?
      Hallo fanderlf,

      Das sind verschiedene Vertragslaufzeiten zu einer ID

      Im Grunde kann man diese beide Zeitraeume auch getrennt bearbeiten.
      Dann füge ich diese halt später zusammen.

      Danke schon mal!

      Viele Grüße

      Martin

      p.s

      Im Grunde kann mann sich es so vor stellen, der erste Zeitraum gibt an, ob eine Kunde bei einem Vertreter einen gültigen Vetrag hatte.
      Der Zweite, in welchem Zeitraum der Kunde alle Voraussetzungen eines potentiellen Kunden erfüllt.
      Zuletzt editiert von Martin R.; 28.02.2012, 10:51. Reason: p.s

      Comment


      • #4
        Hier kann man eine hierarchische Abfrage mit CONNECT BY verwenden:
        Die Zusammenhängenden Zeiten findet man durch
        PRIOR BIS_1=(VON_1)-1
        LEVEL gibt an, wieviel zusammenhängende Sätze gefunden wurden.
        Code:
         WITH DATA AS
            (SELECT '1' AS id,TO_DATE('01.01.2010') AS VON_1,TO_DATE('30.04.2010') AS BIS_1,TO_DATE('01.01.2010') AS VON_2,
            TO_DATE('31.05.2010') AS BIS_2 FROM DUAL UNION ALL
            SELECT '1',TO_DATE('01.05.2010'),TO_DATE('01.01.9999'),TO_DATE('01.06.2010'),TO_DATE('01.01.9999') FROM DUAL UNION ALL
            SELECT '2',TO_DATE('01.01.2005'),TO_DATE('01.01.2009'),TO_DATE('01.01.2005'),TO_DATE('01.01.2009') FROM DUAL UNION ALL
            SELECT '2',TO_DATE('05.01.2009'),TO_DATE('30.04.2010'),TO_DATE('05.01.2009'),TO_DATE('30.04.2010') FROM DUAL UNION ALL
            SELECT '3',TO_DATE('01.01.2010'),TO_DATE('30.04.2010'),TO_DATE('30.04.2010'),TO_DATE('30.04.2010') FROM DUAL UNION ALL
            SELECT '3',TO_DATE('30.04.2009'),TO_DATE('30.04.2010'),TO_DATE('01.05.2010'),TO_DATE('30.04.2010') FROM DUAL UNION ALL
            SELECT '3',TO_DATE('01.05.2010'),TO_DATE('01.10.2010'),TO_DATE('02.05.2010'),TO_DATE('01.10.2010') FROM DUAL UNION ALL
            SELECT '3',TO_DATE('02.10.2010'),TO_DATE('01.10.2011'),TO_DATE('02.05.2010'),TO_DATE('01.01.9999') FROM DUAL UNION ALL
            SELECT '3',TO_DATE('02.10.2011'),TO_DATE('01.01.9999'),TO_DATE('02.05.2010'),TO_DATE('01.01.9999') FROM DUAL UNION ALL
            SELECT '4',TO_DATE('01.01.2010'),TO_DATE('01.10.2011'),TO_DATE('01.01.2010'),TO_DATE('01.10.2011') FROM DUAL UNION ALL
            SELECT '4',TO_DATE('02.12.2011'),TO_DATE('13.05.2011'),TO_DATE('02.05.2010'),TO_DATE('01.10.2011') FROM DUAL UNION ALL
            SELECT '4',TO_DATE('13.05.2011'),TO_DATE('01.01.9999'),TO_DATE('01.10.2011'),TO_DATE('01.01.9999') FROM DUAL)
            SELECT id, level lv, 
                   SYS_CONNECT_BY_PATH(von_1||'-'||bis_1,'+') zeitraum, 
                   CONNECT_BY_ROOT(von_1) startdat, 
                   bis_1 enddat 
              FROM DATA
           CONNECT BY NOCYCLE 
             (PRIOR ID=ID AND PRIOR BIS_1=(VON_1)-1);
        
        
        ID   LV      STARTDAT        ENDDAT            ZEITRAUM
        ----------------------------------------------------------------------------------------
        1	1	01.01.2010	30.04.2010	+01.01.10-30.04.10
        1	2	01.01.2010	01.01.9999	+01.01.10-30.04.10+01.05.10-01.01.99
        1	1	01.05.2010	01.01.9999	+01.05.10-01.01.99
        2	1	01.01.2005	01.01.2009	+01.01.05-01.01.09
        2	1	05.01.2009	30.04.2010	+05.01.09-30.04.10
        3	1	30.04.2009	30.04.2010	+30.04.09-30.04.10
        3	2	30.04.2009	01.10.2010	+30.04.09-30.04.10+01.05.10-01.10.10
        3	3	30.04.2009	01.10.2011	+30.04.09-30.04.10+01.05.10-01.10.10+02.10.10-01.10.11
        3	4	30.04.2009	01.01.9999	+30.04.09-30.04.10+01.05.10-01.10.10+02.10.10-01.10.11+02.10.11-01.01.99
        3	1	01.01.2010	30.04.2010	+01.01.10-30.04.10
        3	2	01.01.2010	01.10.2010	+01.01.10-30.04.10+01.05.10-01.10.10
        3	3	01.01.2010	01.10.2011	+01.01.10-30.04.10+01.05.10-01.10.10+02.10.10-01.10.11
        3	4	01.01.2010	01.01.9999	+01.01.10-30.04.10+01.05.10-01.10.10+02.10.10-01.10.11+02.10.11-01.01.99
        3	1	01.05.2010	01.10.2010	+01.05.10-01.10.10
        3	2	01.05.2010	01.10.2011	+01.05.10-01.10.10+02.10.10-01.10.11
        3	3	01.05.2010	01.01.9999	+01.05.10-01.10.10+02.10.10-01.10.11+02.10.11-01.01.99
        3	1	02.10.2010	01.10.2011	+02.10.10-01.10.11
        3	2	02.10.2010	01.01.9999	+02.10.10-01.10.11+02.10.11-01.01.99
        3	1	02.10.2011	01.01.9999	+02.10.11-01.01.99
        4	1	01.01.2010	01.10.2011	+01.01.10-01.10.11
        4	1	13.05.2011	01.01.9999	+13.05.11-01.01.99
        4	1	02.12.2011	13.05.2011	+02.12.11-13.05.11

        Comment


        • #5
          Daten leicht modifiziert bei ID=4

          Hallo Jum,

          erst einmal vielen Dank!

          Verstehe ich dann richtig, das wenn max(level) dem count(id)entspricht
          ist es ein zusammenhängender Zeitraum ansonsten verschiedene?

          Da ich ja bei den jeweils Zusammenhängenden Zeitraeumen das min(von_1) und das max(bis 1) benötige.


          [highlight=sql]
          WITH DATA AS
          (SELECT '1' AS id,TO_DATE('01.01.2010') AS VON_1,TO_DATE('30.04.2010') AS BIS_1,TO_DATE('01.01.2010') AS VON_2,
          TO_DATE('31.05.2010') AS BIS_2 FROM DUAL UNION ALL
          SELECT '1',TO_DATE('01.05.2010'),TO_DATE('01.01.9999'),TO _DATE('01.06.2010'),TO_DATE('01.01.9999') FROM DUAL UNION ALL
          SELECT '2',TO_DATE('01.01.2005'),TO_DATE('01.01.2009'),TO _DATE('01.01.2005'),TO_DATE('01.01.2009') FROM DUAL UNION ALL
          SELECT '2',TO_DATE('05.01.2009'),TO_DATE('30.04.2010'),TO _DATE('05.01.2009'),TO_DATE('30.04.2010') FROM DUAL UNION ALL
          SELECT '3',TO_DATE('01.01.2010'),TO_DATE('30.04.2010'),TO _DATE('30.04.2010'),TO_DATE('30.04.2010') FROM DUAL UNION ALL
          SELECT '3',TO_DATE('30.04.2009'),TO_DATE('30.04.2010'),TO _DATE('01.05.2010'),TO_DATE('30.04.2010') FROM DUAL UNION ALL
          SELECT '3',TO_DATE('01.05.2010'),TO_DATE('01.10.2010'),TO _DATE('02.05.2010'),TO_DATE('01.10.2010') FROM DUAL UNION ALL
          SELECT '3',TO_DATE('02.10.2010'),TO_DATE('01.10.2011'),TO _DATE('02.05.2010'),TO_DATE('01.01.9999') FROM DUAL UNION ALL
          SELECT '3',TO_DATE('02.10.2011'),TO_DATE('01.01.9999'),TO _DATE('02.05.2010'),TO_DATE('01.01.9999') FROM DUAL UNION ALL
          select '4',TO_DATE('01.01.2010'),TO_DATE('01.10.2011'),TO _DATE('01.01.2010'),TO_DATE('01.10.2011') from DUAL union all
          select '4',TO_DATE('02.10.2011'),TO_DATE('13.05.2011'),TO _DATE('02.05.2010'),TO_DATE('01.10.2011') from DUAL union all
          SELECT '4',TO_DATE('14.05.2011'),TO_DATE('01.01.9999'),TO _DATE('01.10.2011'),TO_DATE('01.01.9999') FROM DUAL)
          SELECT id, level lv,
          SYS_CONNECT_BY_PATH(von_1||'-'||bis_1,'+') zeitraum,
          CONNECT_BY_ROOT(von_1) startdat,
          bis_1 enddat
          FROM DATA
          CONNECT BY NOCYCLE
          (PRIOR ID=ID AND PRIOR BIS_1=(VON_1)-1);[/highlight]
          Also bei id=2

          +01.01.2005-01.01.2009 01.01.2005 01.01.2009
          +05.01.2009-30.04.2010 05.01.2009 30.04.2010

          Und bei ID=4 (Daten wurden o.a. so geaendert, dass es nur einen Zeitraum gibt)

          +01.01.2010-01.10.2011+02.10.2011-13.05.2011+14.05.2011-01.01.9999 01.01.2010 01.01.9999

          Danke nochmals

          Viele Grüße

          Martin

          Comment


          • #6
            Ja, der LEVEL gibt an, wieviel Sätze "zusammengefügt" werden konnten, damit "passen" bei count(id)=max(level) alle id-Bereiche "zusammen".
            Die hierarchischen Abfragen bieten noch weit mehr Möglichkeiten...
            Viel Erfolg!

            Comment


            • #7
              Hallo jum,

              vielen Dank, es funktioniert wunderbar!


              Wie würde denn die hier. Abfrage lauten, wenn Anfangs und Enddatum bei verschiedenen DS gleich sein können bzw, wie ich nun erfahren habe, es sein darf, dass 30 Tage Lücke nicht als solche zählt, sondern als durchgehender Zeitraum ausgewertet wird?

              Edit wir haben das Problem mittels PL/SQL gelöst.
              Die Antwort, wie die Lösung mit sql ausschaut würde mich nat noch sehr interessieren.

              Evtl, falls mal jemand etwasZeit hat;-)


              Vielen dank für Deine Hilfe und Tipps!

              Viele Grüße

              Martin
              Zuletzt editiert von Martin R.; 29.02.2012, 12:15.

              Comment

              Working...
              X