甲骨文設置:
CREATE TABLE diary ("DATE", starthour, endhour) AS
SELECT DATE '2017-04-10', '12:00', '12:15' FROM DUAL UNION ALL
SELECT DATE '2017-04-10', '12:15', '12:30' FROM DUAL UNION ALL -- Immediately follows
SELECT DATE '2017-04-10', '12:45', '13:15' FROM DUAL UNION ALL
SELECT DATE '2017-04-10', '13:00', '14:00' FROM DUAL UNION ALL -- Partly overlaps
SELECT DATE '2017-04-10', '14:30', '15:30' FROM DUAL UNION ALL
SELECT DATE '2017-04-10', '14:45', '15:15' FROM DUAL UNION ALL -- Inside previous
SELECT DATE '2017-04-10', '16:00', '17:00' FROM DUAL;
查詢:
WITH dates (starthour, endhour) AS (
-- Convert your dates to include time components.
SELECT "DATE" + TO_DATE(starthour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI')),
"DATE" + TO_DATE(endhour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI'))
FROM diary
WHERE "DATE" + TO_DATE(starthour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI'))
< :your_end_date
AND "DATE" + TO_DATE(endhour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI'))
> :your_start_date
-- Add zero width entries at the start and end of the range:
UNION ALL SELECT :your_start_date, :your_start_date FROM DUAL
UNION ALL SELECT :your_end_date, :your_end_date FROM DUAL
),
unpivoted (datetime, isStartEnd, cnt) AS (
-- Convert pairs of start/end times to a list of times
-- where the start of an appointment has a corresponding value of +1 and the
-- end of an appointment has a corresponding value of -1. The CNT column
-- is the total of all the previous +1/-1 values.
SELECT datetime,
isStartEnd,
SUM(isStartEnd) OVER (ORDER BY datetime ASC, isStartEnd DESC)
FROM dates
UNPIVOT (datetime FOR isStartEnd IN (starthour AS 1, endhour AS -1))
),
appointment_bounds (startdate, enddate, isStartEnd) AS (
SELECT LAG(datetime, 1) OVER (ORDER BY datetime ASC, isStartEnd DESC),
datetime,
isStartEnd
FROM unpivoted
WHERE (cnt = 0 AND isStartEnd = -1) -- Last time in a group of appointments
OR (cnt = 1 AND isStartEnd = 1) -- First time in a group of appointments
)
SELECT startdate,
enddate
FROM appointment_bounds
WHERE isStartEnd = 1
AND startdate IS NOT NULL;
輸出:
運行與綁定參數:your_start_date
和:your_end_date
爲2017-04-10 11:00:00
和2017-04-10 16:30:00
上述查詢分別爲:
STARTDATE ENDDATE
------------------- -------------------
2017-04-10 11:00:00 2017-04-10 12:00:00
2017-04-10 12:30:00 2017-04-10 12:45:00
2017-04-10 14:00:00 2017-04-10 14:30:00
2017-04-10 15:30:00 2017-04-10 16:00:00
簡單查詢:
WITH dates (starthour, endhour) AS (
-- Convert your dates to include time components.
SELECT "DATE" + TO_DATE(starthour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI')),
"DATE" + TO_DATE(endhour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI'))
FROM diary
WHERE "DATE" + TO_DATE(starthour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI'))
< :your_end_date
AND "DATE" + TO_DATE(endhour, 'HH24:MI') - TO_DATE('00:00', 'HH24:MI'))
> :your_start_date
-- Add zero width entries at the start and end of the range:
UNION ALL SELECT :your_start_date, :your_start_date FROM DUAL
UNION ALL SELECT :your_end_date, :your_end_date FROM DUAL
)
SELECT prev_endhour, starthour
FROM (
SELECT LAG(endhour) OVER (ORDER BY starthour ASC, endhour ASC) AS prev_endhour,
starthour
FROM dates
)
WHERE prev_endhour < starthour;
,郵政您的樣本數據和預期輸出。 – Mansoor
還有你到目前爲止嘗試過的。 –
SELECT * FROM ( SELECT DISTINCT 日期, starthour, endhour FROM 日記 WHERE diary_id = 1025 AND 日期= TO_DATE( '2017年5月1日',「YYYY/MM/DD ') AND( starthour> = to_timestamp('11:00:00.01','HH24:MI:SS.FF') AND endhour <= to_timestamp('11:15:00.01','HH24:MI: SS.FF') ) ) 奧德R BY date ASC, starthour ASC; – Angabo