找到oracle sql中两个日期之间的经过时间

时间:2014-01-13 17:00:12

标签: sql oracle date-arithmetic

我需要找到hh:mm:ss

格式的时间差异
select msglog.id,max(msglog.timestamp) enddate,
   min(msglog.timestamp) startdate,
   enddate - startdate
   from MESSAGELOG msglog
   group by id

在上面的查询中,msglog.timestamp的类型为DATE。

如何在oracle中以正确的格式获取经过的时间或差异?

3 个答案:

答案 0 :(得分:20)

当您减去DATE这两个enddate - startdate值时,您会得到带小数精度的天数差异,因此例如1.5意味着1 1/2天或36小时。您可以使用大量数学将其转换为HH:MI:SS,但更简单的方法是使用NUMTODSINTERVAL函数将小数值转换为INTERVAL DAY TO SECOND值:

  NUMTODSINTERVAL(enddate - startdate, 'DAY')

您认为TO_CHAR函数可以将其格式设置为HH:MI:SS,但它似乎不会那样工作。您可以使用EXTRACT代替TO_CHAR以确保获得前导零:

 TO_CHAR(EXTRACT(HOUR FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')
   || ':' ||
 TO_CHAR(EXTRACT(MINUTE FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')
   || ':' ||
 TO_CHAR(EXTRACT(SECOND FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')

格式代码的00部分指定两个数字,如果需要,前导零。 FM部分删除了格式化结果中的前导空格,如果需要,可以为负号保留。

另请注意,您的查询会获取聚合值,并在同一SELECT列表中使用它们。 Oracle不会让你这样做。尝试这样的事情:

WITH StartEndByID AS (
  SELECT
    msglog.id,
    NUMTODSINTERVAL(max(msglog.timestamp) - min(msglog.timestamp), 'DAY') elapsed
  FROM messagelog msglog
  GROUP BY id
)
SELECT
  id,
  TO_CHAR(EXTRACT(HOUR FROM elapsed), 'FM00') || ':' ||
    TO_CHAR(EXTRACT(MINUTE FROM elapsed), 'FM00') || ':' ||
    TO_CHAR(EXTRACT(SECOND FROM elapsed), 'FM00') AS ElapsedHHMISS
FROM StartEndByID

答案 1 :(得分:15)

Oracle中的日期算术会产生以天为单位的数字。因此,要转换为小时数,您将乘以24然后trunc得到一个整数:

trunc(24 * (enddate - startdate))

要获得分钟数,请将天数值转换为分钟数,将mod()转换为60分钟

mod(trunc(24 * 60 * (enddate - startdate)), 60)

对于秒数,再次将天数转换为秒数,将mod()转换为60:

mod(trunc(24 * 60 * 60 * (enddate - startdate)), 60)

现在您可以将它们放在一起以获取所需的字符串值。

答案 2 :(得分:2)

要在几秒钟内获得差异,您可以使用此

select round(24 * 60 * 60* (TO_DATE('2017/02/17 9:32:25', 'YYYY/MM/DD HH:MI:SS') - TO_DATE('2017/02/17 8:30:30', 'YYYY/MM/DD HH:MI:SS'))) from dual;