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