甲骨文设置:
CREATE TABLE Trip_Dates (Start_Date, End_Date) AS
SELECT TO_DATE('2016-02-01 04:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-02-02 10:00:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL UNION ALL
SELECT TO_DATE('2016-02-02 14:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-02-06 20:00:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL UNION ALL
SELECT TO_DATE('2016-02-01 01:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-02-02 07:00:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
查询:
WITH Dates (dt, start_end) AS (
SELECT GREATEST(start_date, TRUNC(SYSDATE, 'MM')),
1
FROM trip_dates
WHERE start_date < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)
AND end_date > TRUNC(SYSDATE, 'MM')
UNION ALL
SELECT LEAST(end_date, ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)),
-1
FROM trip_dates
WHERE start_date < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)
AND end_date > TRUNC(SYSDATE, 'MM')
ORDER BY 1, 2
)
,range_start_ends (dt, start_end, range_start, range_end) AS (
SELECT d.*,
CASE
WHEN start_end = 1
AND SUM(start_end) OVER (ORDER BY dt) = 1
THEN dt
ELSE NULL
END,
CASE
WHEN start_end = -1
AND SUM(start_end) OVER (ORDER BY dt) = 0
THEN dt
ELSE NULL
END
FROM Dates d
),
worked_days (worked_days) AS (
SELECT range_end - LAG(range_start) IGNORE NULLS OVER (ORDER BY dt)
FROM range_start_ends
)
SELECT (ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)
- TRUNC(SYSDATE, 'MM') -
SUM(worked_days)
) * 24 AS unworked_hours
FROM worked_days;
结果:
UNWORKED_HOURS
--------------
561
来源
2016-02-20 10:17:26
MT0