Po odjęciu dwóch DATE
wartości takie jak enddate - startdate
otrzymujesz różnicę w dniach z dokładnością dziesiętną, więc na przykład 1,5 oznaczałoby 1 1/2 dnia lub 36 godzin. Możesz to przekonwertować na HH:MI:SS
używając dużo matematyki, ale łatwiejszym sposobem jest przekonwertowanie wartości dziesiętnej na INTERVAL DAY TO SECOND
wartość przy użyciu NUMTODSINTERVAL
funkcja:
NUMTODSINTERVAL(enddate - startdate, 'DAY')
Można by pomyśleć, że TO_CHAR
funkcja będzie w stanie sformatować to jako HH:MI:SS
, ale wydaje się, że to nie działa w ten sposób. Możesz użyć EXTRACT
zamiast tego i TO_CHAR
aby upewnić się, że otrzymujesz wiodące zera:
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
część kodu formatu określa dwie cyfry, w razie potrzeby z wiodącym zerem. FM
część usuwa wiodącą spację w sformatowanym wyniku, która w razie potrzeby jest zarezerwowana dla znaku ujemnego.
Pamiętaj też, że Twoje zapytanie pobiera wartości zagregowane i używa ich w tym samym SELECT
lista. Oracle ci na to nie pozwoli. Zamiast tego wypróbuj coś takiego:
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