【发布时间】:2020-08-28 09:06:52
【问题描述】:
我有一个 (Oracle)DB 表,其中 2 列 t1 和 t2 都具有数据类型时间戳。 t2 列可以为空。我需要一个 SQL 查询来给我类似下面的伪代码。
sum ((t2 if t2 !=null else sys.currentTimestamp) - t1)
【问题讨论】:
标签: sql oracle datetime sum sql-null
我有一个 (Oracle)DB 表,其中 2 列 t1 和 t2 都具有数据类型时间戳。 t2 列可以为空。我需要一个 SQL 查询来给我类似下面的伪代码。
sum ((t2 if t2 !=null else sys.currentTimestamp) - t1)
【问题讨论】:
标签: sql oracle datetime sum sql-null
这里有两个问题。首先,如何将默认值替换为空值。这很简单,我们有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 以获取添加的功能。)
与此同时,您可以使用 Oracle Data Cartridge Interface write your own,或使用诸如 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
【讨论】: