Created
January 13, 2015 11:07
-
-
Save radium226/e33e0cd9cc46094d7c04 to your computer and use it in GitHub Desktop.
This is an example on how to compute overlaps on a timeline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- 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