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

Zeitraum in kleinere Zeiträume einteilen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von hkirac, 1 Dezember 2016.

  1. hkirac

    hkirac Neuer Benutzer

    Liebe Community,

    ist es in SQL möglich einen Eintrag mit einem größeren Zeitraum in mehrere Einträge mit kleineren Zeiträumen aufzuspalten. Das Aufspaltekriterium ist hierbei der Kalendertag.

    Klartext: Spalten 'Von' und 'Bis' müssen aufgeteilt werden und in neuen Zeilen auftauchen.

    Beispiel wie der gelb markierte Eintrag aussehen sollte:

    VON BIS
    1. 12/8/2015 7:00:00 AM 12/8/2015 11:59:59 PM
    2. 12/9/2015 0:00:00 AM 12/9/2015 11:59:59 PM
    3. 12/10/2015 0:00:00 AM 12/10/2015 11:59:59 PM
    4. 12/11/2015 0:00:00 AM 12/11/2015 11:59:59 PM
    5. 12/12/2015 0:00:00 AM 12/12/2015 11:59:59 PM
    6. 12/13/2015 0:00:00 AM 12/13/2015 11:59:59 PM
    7. 12/14/2015 0:00:00 AM 12/14/2015 11:59:59 PM
    8. 12/15/2015 0:00:00 AM 12/15/2015 11:59:59 PM
    9. 12/16/2015 0:00:00 AM 12/16/2015 11:59:59 PM
    10. 12/17/2015 0:00:00 AM 12/17/2015 01:00:00 PM


    Wäre dies möglich?

    PS: Optimal wäre es, wenn noch zusätzlich die Wochenenden und Feiertage raus genommen werden könnten.


    Vielen Dank für die Antworten

    Beste Grüße:)
     

    Anhänge:

  2. akretschmer

    akretschmer Datenbank-Guru

    Joa, geht. Zumindest eine Lösung in PostgreSQL kann ich Dir zeigen:

    Code:
    test=*# select * from urlaub ;
      von  |  bis   
    ---------------------+---------------------
     2015-12-08 07:00:00 | 2015-12-17 13:00:00
    (1 Zeile)
    
    test=*# select *, case when extract(dow from d) in (6,0) then 'weekend' else 'working day' end  from generate_series('2015-12-01','2015-12-31','1day'::interval) d left join urlaub u on d.d between u.von and u.bis;
      d  |  von  |  bis  |  case   
    ------------------------+---------------------+---------------------+-------------
     2015-12-01 00:00:00+01 |  |  | working day
     2015-12-02 00:00:00+01 |  |  | working day
     2015-12-03 00:00:00+01 |  |  | working day
     2015-12-04 00:00:00+01 |  |  | working day
     2015-12-05 00:00:00+01 |  |  | weekend
     2015-12-06 00:00:00+01 |  |  | weekend
     2015-12-07 00:00:00+01 |  |  | working day
     2015-12-08 00:00:00+01 |  |  | working day
     2015-12-09 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-10 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-11 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-12 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | weekend
     2015-12-13 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | weekend
     2015-12-14 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-15 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-16 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-17 00:00:00+01 | 2015-12-08 07:00:00 | 2015-12-17 13:00:00 | working day
     2015-12-18 00:00:00+01 |  |  | working day
     2015-12-19 00:00:00+01 |  |  | weekend
     2015-12-20 00:00:00+01 |  |  | weekend
     2015-12-21 00:00:00+01 |  |  | working day
     2015-12-22 00:00:00+01 |  |  | working day
     2015-12-23 00:00:00+01 |  |  | working day
     2015-12-24 00:00:00+01 |  |  | working day
     2015-12-25 00:00:00+01 |  |  | working day
     2015-12-26 00:00:00+01 |  |  | weekend
     2015-12-27 00:00:00+01 |  |  | weekend
     2015-12-28 00:00:00+01 |  |  | working day
     2015-12-29 00:00:00+01 |  |  | working day
     2015-12-30 00:00:00+01 |  |  | working day
     2015-12-31 00:00:00+01 |  |  | working day
    (31 Zeilen)
    
    test=*#
    
    
    
     
  3. hkirac

    hkirac Neuer Benutzer

    Hallo akretschmer,

    vielen Dank für die schnelle Rückmeldung und die kompetente Unterstützung. Die Datenbank ist eine MSQL 2012 ich wüsste jetzt nicht wie ich deine Abfrage umwandeln könnte. Generate_series ist in MSQL nicht möglich soweit ich weiß.

    Danke
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Das ist wohl leider wahr. Evtl. findest Du via Google eine Alternative, oder Du baust Dir (via Stored Proc?) solch eine Tabelle, oder ...
     
  5. ukulele

    ukulele Datenbank-Guru

    Kaum ist man mal wieder ein paar Tage beschäftigt ist das MS-Unterforum wieder mal unproduktiv :)

    Natürlich kriegt man generate_series() in MSSQL nachgebaut, z.B. ganz klassisch mit WITH:
    Code:
    WITH t1(id,von,bis) AS (
       SELECT   1,cast('2015-31-12 00:00:00:000' AS DATETIME),cast('2016-30-01 00:00:00:000' AS DATETIME)
       ), t2 AS (
       SELECT   t1.id,
           t1.von,
           t1.bis,
           datepart(dw,t1.von) AS tag
       FROM   t1
       UNION ALL
       SELECT   t2.id,
           dateadd(day,1,t2.von) AS von,
           t2.bis,
           datepart(dw,dateadd(day,1,t2.von)) AS tag
       FROM   t2
       WHERE   dateadd(day,1,t2.von) <= t2.bis
       )
    SELECT   t2.*
    FROM   t2
    ORDER BY t2.id,t2.von
    Man merke t1 dient hier nur dazu die Tabelle zu simulieren, t2 erstellt dann die Abfolge von Tagen. Das läßt sich jetzt natürlich umbauen so das gleich die richtigen Datensätze mit von / bis raus kommen, einfacher finde ich es aber nachträglich zu filtern:
    Code:
    WITH t1(id,von,bis) AS (
       SELECT   1,cast('2015-30-12 00:00:00:000' AS DATETIME),cast('2016-30-01 00:00:00:000' AS DATETIME)
       ), t2 AS (
       SELECT   t1.id,
           t1.von,
           dateadd(day,5-datepart(dw,t1.von),von) AS bis,
           t1.bis AS bis_ende,
           datepart(dw,t1.von) AS tag
       FROM   t1
       UNION ALL
       SELECT   t2.id,
           dateadd(day,3,t2.bis) AS von,
           (   CASE
             WHEN   dateadd(day,7,t2.bis) > t2.bis_ende
             THEN   t2.bis_ende
             ELSE   dateadd(day,7,t2.bis)
             END ) AS bis,
           t2.bis_ende,
           datepart(dw,dateadd(day,3,t2.bis)) AS tag
       FROM   t2
       WHERE   dateadd(day,3,t2.bis) <= t2.bis_ende
       )
    SELECT   t2.id,
         t2.von,
         t2.bis
    FROM   t2
    ORDER BY t2.id,t2.von,t2.bis
    Ich muss jetzt zugeben läuft noch nicht sauber, startet man am 27.12. gibts Blödsinn das musst du noch sauber schreiben. Da du es eh verstehen musst brauch ich mir jetzt nicht mehr das Hirn zu verrenken. Auch Feiertage musst du mit etwas Aufwand abfangen, geht aber.
     
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