Skip to content

Instantly share code, notes, and snippets.

@radium226
Created January 13, 2015 11:07
Show Gist options
  • Select an option

  • Save radium226/e33e0cd9cc46094d7c04 to your computer and use it in GitHub Desktop.

Select an option

Save radium226/e33e0cd9cc46094d7c04 to your computer and use it in GitHub Desktop.
This is an example on how to compute overlaps on a timeline.
-- 1. T_INTERVALS:
-- [-----------------------------[ #1
-- 08:00 08:30
-- [---------[ #2
-- 08:10 08:20
-- [-------------------[ #3
-- 08:40 09:00
-- [----------[ #4
-- 08:35 08:45
-- [---------[ #5
-- 08:55 09:05
-- [---------[ #6
-- 09:05 09:15
--
-- 2. SQL Query:
-- [-----------------------------[
-- 08:00 08:30
-- [---------------------------------------[
-- 08:35 09:15
--
CREATE TABLE
t_intervals (
begin_time DATE,
end_time DATE,
category VARCHAR2(5),
code VARCHAR2(5)
);
INSERT INTO t_intervals(begin_time, end_time, category, code) VALUES (to_date('08:00', 'HH24:MI'), to_date('08:30', 'HH24:MI'), 'A', '#1');
INSERT INTO t_intervals(begin_time, end_time, category, code) VALUES (to_date('08:10', 'HH24:MI'), to_date('08:20', 'HH24:MI'), 'A', '#2');
INSERT INTO t_intervals(begin_time, end_time, category, code) VALUES (to_date('08:40', 'HH24:MI'), to_date('09:00', 'HH24:MI'), 'A', '#3');
INSERT INTO t_intervals(begin_time, end_time, category, code) VALUES (to_date('08:35', 'HH24:MI'), to_date('08:45', 'HH24:MI'), 'A', '#4');
INSERT INTO t_intervals(begin_time, end_time, category, code) VALUES (to_date('08:55', 'HH24:MI'), to_date('09:05', 'HH24:MI'), 'A', '#5');
INSERT INTO t_intervals(begin_time, end_time, category, code) VALUES (to_date('09:05', 'HH24:MI'), to_date('09:15', 'HH24:MI'), 'A', '#6');
INSERT /*+ APPEND */ INTO t_intervals(begin_time, end_time, category, code) SELECT i.begin_time + 10 / (24 * 60) begin_time, i.end_time + 10 / (24 * 60) end_time, 'B', i.code FROM t_intervals i;
COMMIT;
SELECT
i.category,
LISTAGG(i.code, ', ') WITHIN GROUP(ORDER BY i.begin_time, i.code) codes,
MIN(i.begin_time) begin_time,
MAX(i.end_time) end_time
FROM
(
SELECT
i.category,
i.code,
i.begin_time,
i.end_time,
MAX(i.group_1) OVER(PARTITION BY category ORDER BY i.begin_time ASC) group_2
FROM
(
SELECT
i.category,
i.begin_time,
i.code,
COALESCE(i.end_time, to_date('99991230', 'YYYYMMDD')) end_time,
CASE
WHEN
(i.begin_time NOT BETWEEN MIN(i.begin_time) OVER(PARTITION BY i.category ORDER BY i.begin_time ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AND COALESCE(MAX(i.end_time) OVER(PARTITION BY i.category ORDER BY i.begin_time ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), to_date('99991230', 'YYYYMMDD')))
OR LAG(i.begin_time) OVER(PARTITION BY category ORDER BY i.begin_time ASC) IS NULL
THEN
row_number() OVER(PARTITION BY i.category ORDER BY i.begin_time ASC)
ELSE
-1
END group_1
FROM
t_intervals i
) i
) i
GROUP BY
i.category,
i.group_2;
DROP TABLE
t_intervals;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment