当减去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 )
SQL或PL / SQL中是否有更优雅的方法?
答案 0 :(得分:21)
一种简单的方法:
select extract(day from (ts1-ts2)*86400) from dual;
我们的想法是将间隔值转换为天数86400(= 24 * 60 * 60)。 然后提取'day'值,这实际上是我们想要的第二个值。
答案 1 :(得分: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
通过测试:
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>
答案 2 :(得分:9)
我发现这个有用。显然,如果你使用时间戳进行算术运算,它们会转换为某种内部数据类型,当相互减去时,会将间隔作为数字返回。
容易吗?是。优雅?没有。完成工作?哦是的。
SELECT ( (A + 0) - (B + 0) ) * 24 * 60 * 60
FROM
(
SELECT SYSTIMESTAMP A,
SYSTIMESTAMP - INTERVAL '1' MINUTE B
FROM DUAL
);
答案 3 :(得分:4)
不幸的是,我不认为有一种替代(或更优雅)的方法来计算pl / sql中间隔类型的总秒数。正如this article提到:
... unlike .NET, Oracle provides no simple equivalent to TimeSpan.TotalSeconds.
因此从区间中提取日,小时等并将它们与相应的值相乘似乎是唯一的方法。
答案 4 :(得分:2)
基于zep's answer,为方便起见,我将内容整理成一个函数:
CREATE OR REPLACE FUNCTION intervalToSeconds(
pMinuend TIMESTAMP , pSubtrahend TIMESTAMP ) RETURN NUMBER IS
vDifference INTERVAL DAY TO SECOND ;
vSeconds NUMBER ;
BEGIN
vDifference := pMinuend - pSubtrahend ;
SELECT EXTRACT( DAY FROM vDifference ) * 86400
+ EXTRACT( HOUR FROM vDifference ) * 3600
+ EXTRACT( MINUTE FROM vDifference ) * 60
+ EXTRACT( SECOND FROM vDifference )
INTO
vSeconds
FROM DUAL ;
RETURN vSeconds ;
END intervalToSeconds ;
答案 5 :(得分:1)
使用以下查询:
select (cast(timestamp1 as date)-cast(timestamp2 as date))*24*60*60)
答案 6 :(得分:0)
类似于@Zhaoping Lu的答案,但直接提取秒而不是从天数中获取秒。
SELECT extract(second from (end_date - start_date)) as "Seconds number"
FROM my_table
(在PostgresSQL 9.6.1上工作)
答案 7 :(得分:-1)
将时间戳转换为纳秒的更短方法。
SELECT (EXTRACT(DAY FROM (
SYSTIMESTAMP --Replace line with desired timestamp --Maximum value: TIMESTAMP '3871-04-29 10:39:59.999999999 UTC'
- TIMESTAMP '1970-01-01 00:00:00 UTC') * 24 * 60) * 60 + EXTRACT(SECOND FROM
SYSTIMESTAMP --Replace line with desired timestamp
)) * 1000000000 AS NANOS FROM DUAL;
NANOS
1598434427263027000
一种将纳秒转换为时间戳的方法。
SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + numtodsinterval(
1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS TIMESTAMP FROM dual;
TIMESTAMP
26/08/20 09:33:47,263027000 UTC
如预期的那样,上述方法的结果不受时区的影响。
一种将间隔转换为纳秒的较短方法。
SELECT (EXTRACT(DAY FROM (
INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval --Maximum value: INTERVAL '+694444 10:39:59.999999999' DAY(6) TO SECOND(9) or up to 3871 year
) * 24 * 60) * 60 + EXTRACT(SECOND FROM (
INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval
))) * 1000000000 AS NANOS FROM DUAL;
NANOS
1598434427263027000
一种将纳秒转换为间隔的方法。
SELECT numtodsinterval(
1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS INTERVAL FROM dual;
INTERVAL
+18500 09:33:47.263027
例如,如果要使用毫秒而不是纳秒,则将1000000000替换为1000。
我已经尝试了一些发布的方法,但是在将间隔乘以86400时遇到了一个异常“ ORA-01873:间隔的前导精度太小”,所以我决定发布一种有效的方法为我。
答案 8 :(得分:-2)
选择to_char(ENDTIME,'yyyymmddhh24missff')-to_char(STARTTIME,'yyyymmddhh24missff')AS DUR 从双; yyyymmddhh24miss-将提供SEC的持续时间 yyyymmddhh24mi持续时间(分钟) yyyymmddhh24-持续时间-小时 yyyymmdd天数持续时间