sun*_*uni 9 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
Run Code Online (Sandbox Code Playgroud)
在上面的查询中,msglog.timestamp的类型为DATE.
如何在oracle中以正确的格式获取经过的时间或差异?
Ed *_*bbs 20
当您减去两个DATE值时,就像enddate - startdate得到小数精度的天数差异一样,例如1.5意味着1 1/2天或36小时.您可以将其转换为HH:MI:SS使用大量数学,但更简单的方法是INTERVAL DAY TO SECOND使用NUMTODSINTERVAL函数将十进制值转换为值:
NUMTODSINTERVAL(enddate - startdate, 'DAY')
Run Code Online (Sandbox Code Playgroud)
您认为该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')
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Gri*_*Dog 17
Oracle中的日期算术会生成以天为单位的数字.因此,要转换为小时数,您将乘以24然后trunc得到一个整数:
trunc(24 * (enddate - startdate))
Run Code Online (Sandbox Code Playgroud)
要获得分钟数,请将天数值转换为分钟数,将其转换为mod()60 分钟:
mod(trunc(24 * 60 * (enddate - startdate)), 60)
Run Code Online (Sandbox Code Playgroud)
几秒钟,再次将天数转换为秒数和mod()60天:
mod(trunc(24 * 60 * 60 * (enddate - startdate)), 60)
Run Code Online (Sandbox Code Playgroud)
现在,您可以将它们放在一起以获取所需的字符串值.