当您减去两个 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