0

我有一个(Oracle)DB 表,其中包含 2 列 t1 和 t2 都具有数据类型时间戳。t2 列可以为空。我需要一个 SQL 查询来给我类似下面的伪代码。

sum ((t2 if t2 !=null else sys.currentTimestamp) - t1)
4

1 回答 1

2

这里有两个问题。首先,如何将默认值替换为空值。这很容易,我们有nvlcoalesce。例如:

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
于 2020-08-28T10:35:46.933 回答