SQL查询以空处理对时间戳差异求和

问题描述

我有一个(Oracle)DB表,其中有2列t1和t2,其数据类型均为timestamp。 t2列为空。我需要一个SQL查询来给我类似下面的伪代码。

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

解决方法

这里有两个问题。首先,如何用默认值代替空值。这很容易,我们有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。 (您可以将投票添加到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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...