Rundung der Zeitstempel auf die nächste zweite

Ich habe eine Tabelle mit timestamp-Werte, und ich möchte Runde werden diese beiden Werte auf die nächste Sekunde, aber ich kann es nicht richtig funktionieren.

Meinem test-Daten und Ansätze so weit:

with v_data as
 (select to_timestamp('2012-12-10 10:49:30.00000000',
                      'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
         to_timestamp('2012-12-10 10:49:30',
                      'YYYY-MM-DD HH24:mi:ss') expected
    from dual
  union all
  select to_timestamp('2012-12-10 10:49:30.46300000',
                      'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
         to_timestamp('2012-12-10 10:49:30',
                      'YYYY-MM-DD HH24:mi:ss') expected
    from dual
  union all
  select to_timestamp('2012-12-10 10:49:30.50000000',
                      'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
         to_timestamp('2012-12-10 10:49:31',
                      'YYYY-MM-DD HH24:mi:ss') expected
    from dual
  union all
  select to_timestamp('2012-12-10 10:49:30.56300000',
                      'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
         to_timestamp('2012-12-10 10:49:31',
                      'YYYY-MM-DD HH24:mi:ss') expected

    from dual
  union all
  select to_timestamp('2012-12-10 10:49:30.99999999',
                      'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
         to_timestamp('2012-12-10 10:49:31',
                      'YYYY-MM-DD HH24:mi:ss') expected
    from dual)
select v1.base_val,
       v1.expected,
       v1.base_val + (0.5 / 86400) solution_round,
       cast(v1.base_val as date) as solution_cast,
       extract(second from v1.base_val) - trunc(extract(second from v1.base_val)) fractional_seconds,
       v1.base_val -
       (extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400 solution_add
  from v_data v1

Alle meine Lösungen haben einen Nachteil: Sie

  • solution_round immer rundet
  • solution_cast funktioniert bis auf 11gR1, aber in 11gR2 es immer rundet ab (Ursache: Oracle verändert das Verhalten - es nun schneidet, statt der Rundung, siehe https://forums.oracle.com/forums/thread.jspa?threadID=2242066 )
  • solution_add Renditen 10:49:29 statt 10:49:31 für die letzten drei Zeilen

Ich denke solution_add arbeiten sollte, und ich machte einige blöde Fehler 🙂

EDIT:

Ben ' s-Lösung (siehe unten) funktioniert bei mir, aber unter Berufung auf to_char(timestamp, 'FF') scheint gefährlich zu sein - die Anzahl der Zeichen zurückgegeben, hängt von der definition des Zeitstempels.

Bin ich mit to_char(timestamp, 'FF3') statt, was scheint, um die Rückkehr Millisekunden zuverlässig.

  • Müsste es nicht ein paar Klammern da? x + 0.5 / 86400 == x + (0.5 / 86400)
  • Streng genommen, die Klammern sind nicht notwendig, da die Rangfolge der / höher ist als das + . Aber ich habe Sie trotzdem machen diese anschaulicher.
  • ...ja, das ist es, was ich meinte. 0.5 / 86400 keinen Sinn (x + 0.5 / 86400 ~= x + 0.0000058). Sollte es nicht ( x + 0.5 ) / 86400?
  • Nein, das sollte nicht sein. Ich möchte hinzufügen, eine halbe Sekunde (0.5 / (24*60*60), es abschneiden und verwenden, dass (eine Art "poor man ' s rounding")
  • Ok, ich dachte, wir reden hier über Unix-timestamps. Oracle version klingt ziemlich geschraubt-up.
Schreibe einen Kommentar