问题描述
我有一个(Oracle)DB表,其中有2列t1和t2,其数据类型均为timestamp。 t2列为空。我需要一个SQL查询来给我类似下面的伪代码。
sum ((t2 if t2 !=null else sys.currentTimestamp) - t1)
解决方法
这里有两个问题。首先,如何用默认值代替空值。这很容易,我们有nvl
和coalesce
。例如:
with demo (t1,t2) as
( select timestamp '2020-01-01 00:00:00',timestamp '2020-01-01 01:02:03'
from dual
union all
select timestamp '2020-01-01 00:00:00',null from dual )
select t1,t2,nvl(t2,current_timestamp)
from demo;
T1 T2 NVL(T2,CURRENT_TIMESTAMP)
---------------------- ---------------------- -----------------------------
2020-01-01 00:00:00.00 2020-01-01 01:02:03.00 2020-01-01 01:02:03.000000000
2020-01-01 00:00:00.00 2020-08-28 11:25:22.989000000
最困难的部分是如何求和t2 - nvl(t2,current_timestamp)
。两个时间戳之间的区别是interval day to second
,尽管您可以使用间隔(加,减,乘等)进行算术运算,但当前无法sum
。 (您可以将投票添加到this suggestion on the Oracle Database Ideas forum来添加功能。)
同时,您可以write your own使用Oracle Data Cartridge界面,也可以使用Stew Stryker的解决方法,例如:
with demo (t1,null from dual )
select numtodsinterval(
sum(
((sysdate + (nvl(t2,systimestamp) -t1)) - sysdate) * 86400
+ extract(second from (nvl(t2,systimestamp) -t1))
- trunc(extract(second from (nvl(t2,systimestamp) -t1)))
),'second'
) as duration
from demo;
DURATION
--------------------------------------------------------------------------------
+000000240 12:37:23.646000000