从间隔数据类型中提取总秒数

Ben*_*Ben 30 sql oracle plsql

减去timestamps返回值时是interval数据类型.是否有一种优雅的方法可以将此值转换为间隔中的(毫秒/微秒)总数,即整数.

以下可行,但它不是很漂亮:

select abs( extract( second from interval_difference ) 
          + extract( minute from interval_difference ) * 60 
          + extract( hour from interval_difference ) * 60 * 60 
          + extract( day from interval_difference ) * 60 * 60 * 24
            )
  from ( select systimestamp - (systimestamp - 1) as interval_difference
           from dual )
Run Code Online (Sandbox Code Playgroud)

SQL或PL/SQL中是否有更优雅的方法?

Zha*_* Lu 24

一个简单的方法:

select extract(day from (ts1-ts2)*86400) from dual;
Run Code Online (Sandbox Code Playgroud)

我们的想法是将间隔值转换为天数86400(= 24*60*60).然后提取'day'值,这实际上是我们想要的第二个值.

  • 这仅适用于小间隔 - 1000 秒以下。之后,您将遇到“ORA-01873:间隔的前导精度太小”的问题 (5认同)
  • 我将其改编为使用`extract(来自(ts1-ts2)*86400*1000)/ 1000`来获得毫秒精度. (3认同)

zep*_*zep 20

我希望这有帮助:

zep@dev> select interval_difference
      2        ,sysdate + (interval_difference * 86400) - sysdate as fract_sec_difference
      3  from   (select systimestamp - (systimestamp - 1) as interval_difference
      4          from   dual)
      5 ;

INTERVAL_DIFFERENCE                                                             FRACT_SEC_DIFFERENCE
------------------------------------------------------------------------------- --------------------
+000000001 00:00:00.375000                                                                 86400,375
Run Code Online (Sandbox Code Playgroud)

通过测试:

zep@dev> select interval_difference
      2        ,abs(extract(second from interval_difference) +
      3        extract(minute from interval_difference) * 60 +
      4        extract(hour from interval_difference) * 60 * 60 +
      5        extract(day from interval_difference) * 60 * 60 * 24) as your_sec_difference
      6        ,sysdate + (interval_difference * 86400) - sysdate as fract_sec_difference
      7        ,round(sysdate + (interval_difference * 86400) - sysdate) as sec_difference
      8        ,round((sysdate + (interval_difference * 86400) - sysdate) * 1000) as millisec_difference
      9  from   (select systimestamp - (systimestamp - 1) as interval_difference
     10          from   dual)
     11  /

INTERVAL_DIFFERENCE                                                             YOUR_SEC_DIFFERENCE FRACT_SEC_DIFFERENCE SEC_DIFFERENCE MILLISEC_DIFFERENCE
------------------------------------------------------------------------------- ------------------- -------------------- -------------- -------------------
+000000001 00:00:00.515000                                                                86400,515            86400,515          86401            86400515

zep@dev> 
Run Code Online (Sandbox Code Playgroud)

  • 我最终解释了为什么这在这里工作:http://stackoverflow.com/a/17413839/458741 (3认同)
  • 这对于 Interval_difference 的某些值不起作用。例如: select Interval_difference, sysdate + (interval_difference * 86400) - sysdate as fract_sec_difference from ( select systimestamp - (systimestamp - 1/3) as Interval_difference from Dual ); (2认同)

Wal*_*ldo 9

我发现这个工作.显然,如果你使用时间戳进行算术运算,它们会转换为某种内部数据类型,当相互减去时,会将间隔作为数字返回.

简单?是.优雅?没有.完成工作?哦耶.

SELECT ( (A + 0) - (B + 0) ) * 24 * 60 * 60 
FROM
(
   SELECT SYSTIMESTAMP A,
          SYSTIMESTAMP - INTERVAL '1' MINUTE B
   FROM DUAL
);
Run Code Online (Sandbox Code Playgroud)