При вычитании двух значений DATE
, таких как enddate - startdate
, вы получаете разницу в днях с десятичной точностью, поэтому, например, 1,5 означает 1 1/2 дня или 36 часов. Вы можете конвертировать, что HH:MI:SS
используя много математики, но более простой способ заключается в преобразовании значения десятичного к INTERVAL DAY TO SECOND
значения с помощью функции NUMTODSINTERVAL
:
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
Спасибо за upvote @GriffeyDog и +1 себя! Ваш ответ также будет хорошо работать. Это сводится к множеству математических вычислений и множеству вызовов функций, и я ожидаю, что некоторые люди могут быть более удобными с большим количеством математики. –