Tabelle mit Zeitspanne in einzel Tage umwandeln

Björn

Neuer Benutzer
Beiträge
2
Hallo zusammen!

Ich versuche eben die Welt von MS Access 2007 zu verlassen und mit auf MS SQL 2012 umzustellen.
Soweit komme ich mit SQL ja zurecht - derzeit hänge ich aber bei einem Problem - wie ich Zeitspannen (von-bis - in Tagen) in einzelne Tage umwandeln kann.

Hintergrund - ich möchte Kapazitätsplanungen damit hochrechnen - was ich an Material verbrauchen werde etc.

Also mein Table schaut wie folgt aus:
Task - StartDatum - EndDatum - Material - Einheiten
Arbeit1 - 2013-01-20 - 2013-01-29 - Steine - 30
Arbeit2 - 2013-01-25 - 2013-01-31 - Steine - 28

Daraus folgt -
Arbeit1 - 3 Steine /pro Tag
Arbeit2 - 4 Steine /pro Tag

Am 2013-01-27 - brauche ich somit 7 Steine

Mein Ansatz war ein Grid View zu bekommen - hierzu müsste ich aber die Daten aus der Tabelle - in einzelne Tagesdaten umwandeln.
Sprich:
Arbeit1 - 2013-01-20 - Steine 3
Arbeit1 - 2013-01-21 - Steine 3

etc.

Vielleicht denke ich zu kompliziert... eine Idee wie ich das umsetzten kann?
Zeitspannen konvertieren .. und in eine Tabelle schreiben - so würde ich es mit VB in Access machen...
Da gibts ne bessere Lösung, oder?

Danke
Björn
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.028
Hallo zusammen!

Ich versuche eben die Welt von MS Access 2007 zu verlassen und mit auf MS SQL 2012 umzustellen.
Soweit komme ich mit SQL ja zurecht - derzeit hänge ich aber bei einem Problem - wie ich Zeitspannen (von-bis - in Tagen) in einzelne Tage umwandeln kann.

Hintergrund - ich möchte Kapazitätsplanungen damit hochrechnen - was ich an Material verbrauchen werde etc.

Also mein Table schaut wie folgt aus:
Task - StartDatum - EndDatum - Material - Einheiten
Arbeit1 - 2013-01-20 - 2013-01-29 - Steine - 30
Arbeit2 - 2013-01-25 - 2013-01-31 - Steine - 28

Daraus folgt -
Arbeit1 - 3 Steine /pro Tag
Arbeit2 - 4 Steine /pro Tag

Am 2013-01-27 - brauche ich somit 7 Steine

Mein Ansatz war ein Grid View zu bekommen - hierzu müsste ich aber die Daten aus der Tabelle - in einzelne Tagesdaten umwandeln.
Sprich:
Arbeit1 - 2013-01-20 - Steine 3
Arbeit1 - 2013-01-21 - Steine 3

etc.

Vielleicht denke ich zu kompliziert... eine Idee wie ich das umsetzten kann?
Zeitspannen konvertieren .. und in eine Tabelle schreiben - so würde ich es mit VB in Access machen...
Da gibts ne bessere Lösung, oder?

Danke
Björn


Ich mach daraus erst mal folgendes:

Code:
test=*# select * from bjoern ;
  task   |     sd     |     ed     | anzahl |          dauer
---------+------------+------------+--------+-------------------------
 arbeit1 | 2013-01-20 | 2013-01-29 |     30 | [2013-01-20,2013-01-30)
 arbeit2 | 2013-01-25 | 2013-01-31 |     28 | [2013-01-25,2013-02-01)
(2 rows)

Die Spalte 'dauer' ist vom Typ DATERANGE, ist ein, finde ich, cooles Feature von PG. Ist hier redundant zu sd,ed (steht für startdatum, enddatum).

Daraus kann ich abfragen, was pro Tag und pro task gebraucht wird:

Code:
test=*# select task,dauer, case when dauer @> ('2013-01-10'::date + s * '1day'::interval)::date then anzahl / (ed-sd)  else 0 end as steine, ('2013-01-10'::date + s * '1day'::interval)::date as datum from bjoern, generate_Series(0,20) s ;                                                          
  task   |          dauer          | steine |   datum
---------+-------------------------+--------+------------
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-10
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-10
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-11
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-11
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-12
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-12
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-13
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-13
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-14
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-14
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-15
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-15
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-16
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-16
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-17
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-17
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-18
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-18
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-19
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-19
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-20
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-20
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-21
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-21
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-22
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-22
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-23
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-23
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-24
 arbeit2 | [2013-01-25,2013-02-01) |      0 | 2013-01-24
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-25
 arbeit2 | [2013-01-25,2013-02-01) |      4 | 2013-01-25
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-26
 arbeit2 | [2013-01-25,2013-02-01) |      4 | 2013-01-26
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-27
 arbeit2 | [2013-01-25,2013-02-01) |      4 | 2013-01-27
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-28
 arbeit2 | [2013-01-25,2013-02-01) |      4 | 2013-01-28
 arbeit1 | [2013-01-20,2013-01-30) |      3 | 2013-01-29
 arbeit2 | [2013-01-25,2013-02-01) |      4 | 2013-01-29
 arbeit1 | [2013-01-20,2013-01-30) |      0 | 2013-01-30
 arbeit2 | [2013-01-25,2013-02-01) |      4 | 2013-01-30
(42 rows)

Daraus nun wieder die Anzahl der Steine pro Tag zu aggregieren ist dann easy.

Code:
test=*# select datum, sum(steine) from (select task,dauer, case when dauer @> ('2013-01-10'::date + s * '1day'::interval)::date then anzahl / (ed-sd)  else 0 end as steine, ('2013-01-10'::date + s * '1day'::interval)::date as datum from bjoern, generate_Series(0,20) s )foo group by datum order by datum;
   datum    | sum
------------+-----
 2013-01-10 |   0
 2013-01-11 |   0
 2013-01-12 |   0
 2013-01-13 |   0
 2013-01-14 |   0
 2013-01-15 |   0
 2013-01-16 |   0
 2013-01-17 |   0
 2013-01-18 |   0
 2013-01-19 |   0
 2013-01-20 |   3
 2013-01-21 |   3
 2013-01-22 |   3
 2013-01-23 |   3
 2013-01-24 |   3
 2013-01-25 |   7
 2013-01-26 |   7
 2013-01-27 |   7
 2013-01-28 |   7
 2013-01-29 |   7
 2013-01-30 |   4
(21 rows)

Vielleicht hilft es ja, ich verwende aber PostgreSQL, mußt halt anpassen.


Andreas
 

Björn

Neuer Benutzer
Beiträge
2
Hallo Andreas,

da hat PostgreSQL aber ein geniales feature mit dem DATERANGE... kenne ich noch nicht in MSSql... aber evtl gibts da ja etwas was ich noch nicht kenne. Mal sehen wie ich das übersetzten kann...

Ansonsten - ganau so habe ich mir das vorgestellt. Danke!

Björn
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.028
Hallo Andreas,

da hat PostgreSQL aber ein geniales feature mit dem DATERANGE... kenne ich noch nicht in MSSql... aber evtl gibts da ja etwas was ich noch nicht kenne.
Björn

Ja, das ist echt cool, geht auch mit INT oder numerischen Typen. Und man kann sogar Exclusion Constraints definieren: innerhalb einer Spalte dürfen sich solche Ranges nicht überlappen. (das hier übliche Beispiel sind Zimmerreservierungen für ein Hotel, um Doppelbelegung zu verhindern) Da geht einiges, aber soweit ich weiß, kann das keine andere namhafte DB. Man kann das sicher auch immer anders lösen, aber ungleich aufwändiger, und exclusion constraints sind faktisch gar nicht anders abbildbar. Naja, für Deinen Fall hab ich halt mal verwendet ;-)

Andreas
 
Oben