Имам таблица, съдържаща стойности на клеймо за време и искам да закръгля всяка от тези стойности до най-близката секунда, но не мога да я накарам да работи правилно.
Моите тестови данни и подходи досега:
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
Всички мои решения имат недостатък:
- solution_round винаги закръгля нагоре
- solution_cast работи до 11gR1, но в 11gR2 винаги закръгля надолу (причина: Oracle промени поведението - сега отрязва вместо закръгляне, вижте https://forums.oracle.com/forums/thread.jspa?threadID=2242066 )
- solution_add връща 10:49:29 вместо 10:49:31 за последните три реда
Предполагам, че solution_add трябва да работи и току-що направих глупава грешка :-)
РЕДАКТИРАНЕ:
Решението на Бен (вижте по-долу) работи за мен, но разчитането на to_char(timestamp, 'FF') изглежда опасно - броят на върнатите цифри зависи от дефиницията на времевия знак.
Вместо това използвам to_char(timestamp, 'FF3'), което изглежда надеждно връща милисекунди.
x + 0.5 / 86400 == x + (0.5 / 86400)
- person JJJ   schedule 10.12.2012x + 0.5 / 86400 ~= x + 0.0000058
). Не трябва ли да е( x + 0.5 ) / 86400
? - person JJJ   schedule 10.12.2012