我有一个(Oracle)DB 表,其中包含 2 列 t1 和 t2 都具有数据类型时间戳。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
。(您可以在 Oracle Database Ideas 论坛上为该建议投票,以获得添加的功能。)
同时,您可以使用 Oracle Data Cartridge Interface自己编写,也可以使用 Stew Stryker 提供的解决方法,例如:
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 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