Zeitraum in kleinere Zeiträume einteilen

hkirac

Neuer Benutzer
Beiträge
2
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

  • SQLAuszug.PNG
    SQLAuszug.PNG
    44,7 KB · Aufrufe: 5
Werbung:
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=*#
 
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
 
Werbung:
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.
 
Zurück
Oben