Khi bạn trừ hai DATE
các giá trị như enddate - startdate
bạn nhận được sự khác biệt về ngày với độ chính xác thập phân, vì vậy, ví dụ:1,5 sẽ có nghĩa là 1 ngày rưỡi hoặc 36 giờ. Bạn có thể chuyển đổi thành HH:MI:SS
sử dụng nhiều phép toán, nhưng một cách dễ dàng hơn là chuyển đổi giá trị thập phân thành INTERVAL DAY TO SECOND
bằng cách sử dụng NUMTODSINTERVAL
chức năng:
NUMTODSINTERVAL(enddate - startdate, 'DAY')
Bạn sẽ nghĩ rằng TO_CHAR
hàm sẽ có thể định dạng nó thành HH:MI:SS
, nhưng nó dường như không hoạt động theo cách đó. Bạn có thể sử dụng EXTRACT
thay vào đó, và TO_CHAR
để đảm bảo bạn nhận được các số 0 ở đầu:
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
một phần của mã định dạng chỉ định hai chữ số, với số 0 ở đầu nếu cần. FM
phần này được loại bỏ khoảng trống ở đầu trong kết quả đã định dạng, phần này được dành cho dấu âm nếu cần.
Cũng lưu ý rằng truy vấn của bạn nhận các giá trị tổng hợp và sử dụng chúng trong cùng một SELECT
danh sách. Oracle sẽ không cho phép bạn làm điều này. Thay vào đó, hãy thử một cái gì đó như thế này:
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