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

Tabelle mit Zeitspanne in einzel Tage umwandeln

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Björn, 2 Februar 2013.

  1. Björn

    Björn Neuer Benutzer

    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
     
  2. akretschmer

    akretschmer Datenbank-Guru


    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
     
  3. Björn

    Björn Neuer Benutzer

    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
     
  4. akretschmer

    akretschmer Datenbank-Guru

    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
     
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