Oracle SQL小时HH:MM:SS中日期之间的差异

时间:2018-06-13 11:11:41

标签: sql oracle date-difference

我已经有一个字符串来计算我从堆栈中获得的两个日期之间的小时差异:

24 *  (to_date(to_char(stp.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DD hh24:mi:ss') -
(to_date(to_char(adhh.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DD hh24:mi:ss'))) diff_hours

但我希望将其视为HH:MM:SS

以下是2个日期/时间示例: STP日期26-Feb-18 12.59.21 ADHH日期26-Feb-18 12.59.32

所以我希望它说区别是00:00:11(11秒)

目前我的结果为-0.003小时

一如既往地感谢

5 个答案:

答案 0 :(得分:2)

假设列已经是日期,因此您正在进行的字符串转换是没有意义的,并且差异总是小于一天,您可以这样做:

to_char(date '1970-01-01' + abs(stp.created_date - adhh.created_date), 'HH24:MI:SS')

这将日期之间的差异作为一天的一小部分;通过abs()确保它是正面的;然后将该部分重新添加到名义上的日期,该日期的时间为午夜。然后它将其转换为字符串,仅查看时间。

快速演示:

-- CTEs to supply the two date/times
with stp (created_date) as (
  select cast(timestamp '2018-02-26 12:59:21' as date) from dual
),
adhh (created_date) as (
  select cast(timestamp '2018-02-26 12:59:32' as date) from dual
)
select to_char(date '1970-01-01' + abs(stp.created_date - adhh.created_date), 'HH24:MI:SS')
from stp cross join adhh;

TO_CHAR(
--------
00:00:11

如果差异可能超过一天,而不是一年,您可以将格式模型更改为'FMDDD FMHH24:MI:SS',这将在开始时显示完整的日期。

答案 1 :(得分:2)

假设列已经是DATE个值(如果没有,我强烈建议您更改它),您可以将它们转换为时间戳。仅转换一个值就足够了,但当然可以转换它们。

CAST(stp.created_date AS TIMESTAMP) - adhh.created_date AS dif

结果是INTERVAL DAY TO SECOND值,其固定输出格式为DDD HH:MI:SS.FF。为了获得所需的格式,您可以使用

REGEXP_SUBSTR(CAST(stp.created_date AS TIMESTAMP) - adhh.created_date, '\d{2}:\d{2}:\d{2}') AS dif

注意,TO_CHAR不适用于间隔。因此,您必须使用REGEXP或使用EXTRACT(... FROM ...)

提取组件

答案 2 :(得分:1)

我建议你在查询中做些小改动

SELECT 
TO_CHAR(TRUNC(x/3600),'FM9900') || ':' ||
TO_CHAR(TRUNC(MOD(x,3600)/60),'FM00') || ':' ||
TO_CHAR(MOD(x,60),'FM00')
 FROM DUAL   

将上述查询中的“x”替换为结果列

24 *  (
to_date(to_char(stp.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DD hh24:mi:ss') -
(to_date(to_char(adhh.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DDhh24:mi:ss')))

希望这会有所帮助..

答案 3 :(得分:0)

您的列看起来已经是DATE格式(它们应该是!)。 在这种情况下,您可以将日期之间的差异作为DAY TO SECOND INTERVAL。使用NUMTODSINTERVAL功能。 然后使用EXTRACT函数,您可以获得小时,分钟和秒的间隔。

以下是一个示例查询。

WITH
    stp (created_date)
    AS
        (SELECT CAST (TIMESTAMP '2018-02-26 12:59:21' AS DATE) FROM DUAL),
    adhh (created_date)
    AS
        (SELECT CAST (TIMESTAMP '2018-02-26 12:59:32' AS DATE) FROM DUAL)
SELECT    LPAD (EXTRACT (HOUR FROM diff_int), 2, '0')   -- get hours from interval
       || ':'
       || LPAD (EXTRACT (MINUTE FROM diff_int), 2, '0') -- get minutes from interval
       || ':'
       || LPAD (EXTRACT (SECOND FROM diff_int), 2, '0') -- get seconds from interval
           AS diff_hours
FROM (SELECT NUMTODSINTERVAL (  -- get difference between the dates as an interval
                 b.created_date
                 - a.created_date,
                 'DAY'
             )
                 diff_int
      FROM stp a,
           adhh b);

结果如下。

DIFF_HOURS

零时00分11秒

答案 4 :(得分:0)

您可以将其转换为间隔,然后使用TO_CHAR将间隔转换为字符串:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE STP ( id INT, created_date DATE );
CREATE TABLE ADHH ( id INT, created_date DATE );

INSERT INTO STP  values ( 1, TIMESTAMP '2018-02-26 12:59:21' );
INSERT INTO STP  values ( 2, TIMESTAMP '2018-02-26 12:00:30' );
INSERT INTO ADHH values ( 1, TIMESTAMP '2018-02-26 12:59:32' );
INSERT INTO ADHH values ( 2, TIMESTAMP '2018-02-26 12:00:00' );

查询1

SELECT TO_CHAR(
         ( s.created_date - a.created_date ) DAY(1) TO SECOND(0)
       ) AS diff
FROM   STP s
       INNER JOIN ADHH a
       ON ( s.id = a.id )

<强> Results

|        DIFF |
|-------------|
| -0 00:00:11 |
| +0 00:00:30 |

查询2 :如果您没有日期组件(即日期总是小于24小时),那么只需替换0子字符串:

SELECT REPLACE(
         ( s.created_date - a.created_date ) DAY(1) TO SECOND(0),
         '0 '
       ) AS diff
FROM   STP s
       INNER JOIN ADHH a
       ON ( s.id = a.id )

<强> Results

|      DIFF |
|-----------|
| -00:00:11 |
| +00:00:30 |