Aug 28

Schon mal versucht einen Aggregations-SQL nach anderen Werten als den Format-Strings die mit to_date, to_char benutzt werden duerfen zu bauen ?

Ist garnicht so simpel. Ein

select count(*),attribut,to_char(creationdate,'DD.MM.YYYY')
 from tabelle
 group by attribut,trunc(creationdate,'DD.MM.YYYY')

ist noch fuer jedermann verstaendlich. Auch wenn man nach Stunden gruppieren will, geht das noch schmerzfrei (‘HH’). Was aber wenn man auf 15Minuten Ebene Aggregieren soll ? Ohne Kunstgriff geht es nicht. Hier der to_date String:

 to_date(to_char(sysdate,'DD.MM.YYYY') ||
         ' ' ||
         trunc(to_number(to_char(sysdate,'SSSSS'))/900)*900,
         'DD.MM.YYYY SSSSS')

Was passiert hier ?

Zunächst wird die aktuelle Zeit (im Select ist es natuerlich das zu gruppierende Feld) in Sekunden nach Mitternacht umgewandelt. Nun dividieren wir das Ergebniss durch 900 (15 Minuten = 900 Sekunden) und schnibbeln die Nachkommastellen ab. Anschliessend das ganze wieder mit 900 Multiplizieren, und wir haben jede Erdenkliche Uhrzeit auf die letzte Viertelstunde (ab-)gerundet. (Schlaue Menschen koennten jetzt sagen, Mensch Joerch, nimm doch DIV, MOD gibts unter Oracle schliesslich auch -> DIV gibts leider NICHT). So, jetzt packen wir noch das Datum wieder davor (ist ja durch die Umwandlung in Sek. nach Mitternacht verloren gegangen) und konvertieren das ganze wieder in ein Datum. Fertig ist der Viertelstundenaggregator 🙂 Bezogen auf das obige Beispiel lautet unserer (zugegebenermassen unlesbarerer Spruch) wie folgt:


select count(*),attribut,
 to_date(to_char(creationdate,'DD.MM.YYYY') ||
         ' ' ||
         trunc(to_number(to_char(creationdate,'SSSSS'))/900)*900,
         'DD.MM.YYYY SSSSS')
 from tabelle
 group by attribut,
 to_date(to_char(creationdate,'DD.MM.YYYY') ||
         ' ' ||
         trunc(to_number(to_char(creationdate,'SSSSS'))/900)*900,
         'DD.MM.YYYY SSSSS')

Leave a Reply

You must be logged in to post a comment.

preload preload preload