datumssprünge kalenderwochen, die woche 52...

also, kleine sache noch:
ich stehe jetzt vor dem problem, das ein “Andreas Kretschmer” 2004 gehabt hat, zumindest laut google… :slight_smile:

fogender code:

select city_id,   count(id) as bestellungen, 
[color=#008000]to_char(submitted_at,'yyyy mm') as wann[/color]

 from cart_order where city_id in ( select city_id from (select
 sum(case when ( to_char(submitted_at,'yyyy mm')='2011 01') then 1 else 0 end) as anfang, 
sum(case when ( to_char(submitted_at,'yyyy mm')='2011 07')  then 1 else 0 end) as ende ,
city_id from orders group by city_id ) foo 
where anfang>0 and ende>0 order by cast( ende as float)/cast(NULLIF(anfang,0)as float) desc limit 10 ) 

 group by city_id, [color=#008000]wann [/color] 
order by [color=#008000]wann[/color],city_id

ergibt

[TABLE]
[TR]
city_idbestellungenwann[/TR]
[TR=“class: data1”]
[TD][RIGHT]20[/RIGHT]
[/TD]
[TD][RIGHT]12[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]544[/RIGHT]
[/TD]
[TD][RIGHT]12[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]679[/RIGHT]
[/TD]
[TD][RIGHT]2[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]680[/RIGHT]
[/TD]
[TD][RIGHT]3[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]686[/RIGHT]
[/TD]
[TD][RIGHT]4[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]688[/RIGHT]
[/TD]
[TD][RIGHT]13[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]876[/RIGHT]
[/TD]
[TD][RIGHT]1[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]877[/RIGHT]
[/TD]
[TD][RIGHT]1[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]908[/RIGHT]
[/TD]
[TD][RIGHT]4[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]1082[/RIGHT]
[/TD]
[TD][RIGHT]15[/RIGHT]
[/TD]
[TD]2011 01[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]20[/RIGHT]
[/TD]
[TD][RIGHT]11[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]544[/RIGHT]
[/TD]
[TD][RIGHT]12[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]679[/RIGHT]
[/TD]
[TD][RIGHT]2[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]680[/RIGHT]
[/TD]
[TD][RIGHT]1[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]686[/RIGHT]
[/TD]
[TD][RIGHT]2[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]688[/RIGHT]
[/TD]
[TD][RIGHT]14[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data1”]
[TD][RIGHT]876[/RIGHT]
[/TD]
[TD][RIGHT]1[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[TR=“class: data2”]
[TD][RIGHT]908[/RIGHT]
[/TD]
[TD][RIGHT]5[/RIGHT]
[/TD]
[TD]2011 02[/TD]
[/TR]
[/TABLE]
usw usw

ergeben sollte es eine tabelle

[TABLE]
[TR]
[TD]city_id
[/TD]
[TD]2011 01
[/TD]
[TD]2011 02
[/TD]
[TD]2011 03
[/TD]
[TD]usw,dynamisch
[/TD]
[/TR]
[TR]
[TD]20
[/TD]
[TD]12
[/TD]
[TD]11
[/TD]
[TD]…
[/TD]
[TD][/TD]
[/TR]
[TR]
[TD]544
[/TD]
[TD]12
[/TD]
[TD]12
[/TD]
[TD]…
[/TD]
[TD][/TD]
[/TR]
[TR]
[TD]679
[/TD]
[TD]2
[/TD]
[TD]2
[/TD]
[TD]0
[/TD]
[TD][/TD]
[/TR]
[TR]
[TD]usw
[/TD]
[TD]…
[/TD]
[TD]…
[/TD]
[TD]…
[/TD]
[TD]…
[/TD]
[/TR]
[/TABLE]

wobei, wie rot markiert, auch 0 als 0 eingetragen werden soll.
die frage dannach ist auf diversen foren verteilt, aber die antwort habe ich nicht gefunden…

Ich kenne Deine Daten nicht, vermute aber, du suchst die Funktion COALESCE().


Andreas

Ihr müsst da mit einbeziehen, das verschiedene Länder die Kalenderwochen anders berechnen.
Eine allgemeingültige Funktion - eingebaut in die Datenbank - kann es da also nicht geben.

Oh, und bezüglich Konferenz: wenn man da hinkommt, dann lernt man natürlich etwas.
Das kannst du doch so deinem Arbeitgeber verkaufen, oder?
Und da ihr PostgreSQL einsetzt, kann von deinem Arbeitgeber auch noch jemand mitkommen.
Und Sponsoringmöglichkeiten bieten wir auch an :wink:

Hallo allerseits,

ich bin auf der Suche nach der Lösung für ein sehr ähnlich gelagertes Problem auf diesen zugegebenermaßen etwas älteren Thread gestoßen. Das SQL


hat damals das richtige Ergebnis geliefert:

Ich habe nun das Ausgangsdatum 2 Jahre in die Zukunft auf ‘2012-12-25’ gesetzt, und schon ergeben sich die altbekannten Probleme, das Ergebnis lautet nämlich nun:

datum      | menge | my_week
2012-12-25 | 20    | 2012_ 52
2012-12-26 | 44    | 2012_ 52
2012-12-27 | 81    | 2012_ 52
2012-12-28 | 87    | 2012_ 52
2012-12-29 | 87    | 2012_ 52
2012-12-30 | 43    | 2012_ 52
2012-12-31 | 16    |[color=#ff0000] 2012_ 01[/color]
2013-01-01 | 81    |[color=#ff0000] 2012_ 01[/color]
2013-01-02 | 90    |[color=#ff0000] 2012_ 01[/color]
2013-01-03 | 45    |[color=#ff0000] 2012_ 01[/color]
2013-01-04 | 39    |[color=#ff0000] 2012_ 01[/color]
2013-01-05 | 65    |[color=#ff0000] 2012_ 01[/color]
2013-01-06 | 20    |[color=#ff0000] 2012_ 01[/color]
2013-01-07 | 51    | 2013_ 02
2013-01-08 | 32    | 2013_ 02
2013-01-09 | 93    | 2013_ 02
2013-01-10 | 74    | 2013_ 02
2013-01-11 | 70    | 2013_ 02
2013-01-12 | 64    | 2013_ 02
2013-01-13 | 10    | 2013_ 02
2013-01-14 | 98    | 2013_ 03
Datum      | Menge | KW
           | 356   | [color=#ff0000]2012_ 01[/color]
           | 362   | 2012_ 52
           | 394   | 2013_ 02
           | 98    | 2013_ 03

Wie man sieht, wird hier die erste KW 2013 als erste KW 2012 angegeben, dagegen gibt es keine erste KW 2013.

Mein ursprüngliches Problem besteht darin, dass ich Daten über mehrere Jahre hinweg für Berichte per SQL Query bereitstellen und anschließend mit einem Reporting Tool aufbereiten muss, und diese Daten nach Jahren und KWs zusammengefasst und sortiert sein müssen. Dabei stoße ich immer wieder darauf, dass die letzten Tage eines Jahres mit den ersten Tagen des gleichen Jahres zusammengeworfen werden, sobald die letzten Tage des Jahres in der ersten KW des nächsten Jahres liegen, wie hier der 31.12.2012, der ja bekanntlich wie die folgenden Tage bis zum 06.01.2013 in der ersten KW 2013 liegt.
Bisher habe ich immer mit irgendwelchen Workarounds gearbeitet, musste dafür aber auch jedes Jahr von neuem diese Berichte anfassen und ändern.

Meine Frage nun: gibt es so etwas wie eine allgemeine Lösung in SQL für dieses Problem? Ich meine so etwas wie eine Verknüpfung der Kalenderwoche mit dem richtigen dazugehörenden Jahr?

Du kannst auch to_char() verwenden:

psql (9.2.1)
Type "help" for help.

postgres=> select to_char(date '2012-12-31', 'WW');
 to_char
---------
 53
(1 row)

postgres=>

bzw. Wenn Du die ISO Definition der Wochennummern benötigst (wie es in Deutschland der Fall ist)

postgres=> select to_char(date '2012-12-31', 'IW');
 to_char
---------
 01
(1 row)


Time: 0,467 ms
postgres=>

Details dazu im Handbuch: PostgreSQL: Documentation: 9.2: Data Type Formatting Functions

Das sind meines Wissens die beiden gültigen Standards für die Berechnung der Wochennummer.

select datum,
       to_char(datum, 'YYYY_IW') as iso_woche,
       to_char(datum, 'YYYY_WW') as woche
from (
  select ('2010-12-25'::date + s * interval '1' day)::date as datum
  from
    generate_series(0,20) s
) t

Liefert dann folgendes:

datum      | iso_woche | woche  
-----------+-----------+--------
2010-12-25 | 2010_51   | 2010_52
2010-12-26 | 2010_51   | 2010_52
2010-12-27 | 2010_52   | 2010_52
2010-12-28 | 2010_52   | 2010_52
2010-12-29 | 2010_52   | 2010_52
2010-12-30 | 2010_52   | 2010_52
2010-12-31 | 2010_52   | 2010_53
2011-01-01 | 2011_52   | 2011_01
2011-01-02 | 2011_52   | 2011_01
2011-01-03 | 2011_01   | 2011_01
2011-01-04 | 2011_01   | 2011_01
2011-01-05 | 2011_01   | 2011_01
2011-01-06 | 2011_01   | 2011_01
2011-01-07 | 2011_01   | 2011_01
2011-01-08 | 2011_01   | 2011_02
2011-01-09 | 2011_01   | 2011_02
2011-01-10 | 2011_02   | 2011_02
2011-01-11 | 2011_02   | 2011_02
2011-01-12 | 2011_02   | 2011_02
2011-01-13 | 2011_02   | 2011_02
2011-01-14 | 2011_02   | 2011_02

Hi castorp,

danke für Deine Antwort, sie liefert jedoch auch falsche (oder vllt besser nicht-richtige?) Ergebnisse.
Teste Dein letztes SQL bitte mal mit dem 25.12.2012 als Ausgangsdatum. Dann taucht die erste KW 2012 als KW für den 31.12.2012 auf, was definitiv nicht richtig ist. Alles andere ist dann wieder soweit ok. Wobei ich gerade sehe, daß Dein Beispiel für den 01.01. und 02.01.2011 das falsche Jahr liefern - und das war eben mein eigentliches Problem.
Ich habe in der Zwischenzeit aber eine Lösung gefunden:

select datum,
       to_char(datum, '[color=#ff0000]IYYY_IW[/color]') as iso_woche
from (
  select ('2012-12-25'::date + s * interval '1' day)::date as datum
  from
    generate_series(0,20) s
) t

(Ich habe einfach mal meine Lösung in Dein Beispiel eingebaut.) Dadurch wird das richtige “ISO-Jahr” zur ISO-Woche angegeben. Darauf gekommen bin ich beim x-ten Mal lesen der Doku, ich denke, das ist die Geschichte mit dem Wald und den Bäumen…

Mittlerweile habe ich meine abzuliefernden Berichte auf diese Weise umgestellt, und bis jetzt passen sie - ohne Workarounds ! :slight_smile:

Trotzdem noch mal Danke für den Denkanstoß.

Den Satz verstehe ich nicht.

Der 31.12.2012 liegt in der KW 01 von 2013, das ist schon richtig. Laut DIN/ISO ist KW 1 die Woche in der der 4. Januar fällt.

Und select to_char(date ‘2012-12-31’, ‘IYYY_IW’) liefert demnach vollkommen korrekt 2013_01

Das ist richtig, mein Satz bezog sich auf Dein folgendes SQL:

Dort hast Du noch das “normale” ‘YYYY’ für die Ermittlung des Jahres des Datums genutzt, welches zwar das richtige Jahr zum Datum liefert, aber eben das falsche Jahr zur ISO-Woche. Ich hoffe ich habe mich verständlich ausgedrückt.

Ah, jetzt habe ich es verstanden.
(Ja, das war ein Flüchtigkeitsfehler von mir, sorry.)