Oracle 时间相减时精度丢失问题
首先此问题发生于一个很巧然的需求(后面简单介绍);说巧然是因为发生的概率实在是非常小,但其在11g版本中也依然存在。
见下面SQL语句:
select (d1 - d2) * 24 * 60 * 60 as diff1,
(d2 - d3) * 24 * 60 * 60 as diff2,
floor(60 / 15) f,
floor((d1 - d2) * 24 * 60 * 60 / 15) f2,
floor((d2 - d3) * 24 * 60 * 60 / 15) f3
from (select to_date('2013-6-22 00:00:00', 'yyyy-mm-dd hh24:mi:ss') as d1,
to_date('2013-6-21 23:59:00', 'yyyy-mm-dd hh24:mi:ss') as d2,
to_date('2013-6-21 23:58:00', 'yyyy-mm-dd hh24:mi:ss') as d3
from dual)
执行结果:
DIFF1 DIFF2 F F2 F3
60 60 4 3 4
SQL语句目的是对两两时间相减得出的秒数后除15取整。(floor为Oracle里自带的取整函数),从sql里我们很简单的得出 (d1与d2) 和 (d2与d3) 相差秒数都为60,但f2结果却为3,明显不对。f3却又是正确的。
可以猜测的是d1(跨天时间)在与d2相减后转化为秒时发生了精度丢失;因此d1-d2 不对,d2-d3没有问题。
在得知此问题后,解决方法是在取整前先对结果进行四舍五入
即:
floor(round((d1 - d2) * 24 * 60 * 60) / 15) f2
到此我们知道发生此问题的概率实在是很小吧,首先若只是单纯的针对时间相减并转化为单位秒还不会有问题,但如果需要进一步对值进行运算并取整就要小心了,若减数刚好跨天就可能会存在错误! 在此提出来希望为大家借鉴。