Created
January 13, 2015 14:16
-
-
Save radium226/543dda45d82e9bd4eafd to your computer and use it in GitHub Desktop.
Example on match intervals presence at the same time.
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
| -- T_INTERVALS: | |
| -- [-----------------------------[ #1 O | |
| -- 08:00 08:30 | |
| -- [---------[ #2 X | |
| -- 08:10 08:20 | |
| -- [-------------------[ #3 O | |
| -- 08:40 09:00 | |
| -- [----------[ #4 X | |
| -- 08:35 08:45 | |
| -- [---------[ #5 O | |
| -- 08:55 09:05 | |
| -- [---------[ #6 O | |
| -- 09:05 09:15 | |
| -- [---------[ #7 O | |
| -- 08:10 08:20 | |
| -- [--------------[ #8 X | |
| -- 08:10 08:25 | |
| -- | |
| -- SQL Query: | |
| -- [--------------[ | |
| -- 08:10 08:25 | |
| -- [-----[ | |
| -- 08:40 08:45 | |
| -- | |
| CREATE TABLE | |
| t_intervals ( | |
| begin_time DATE, | |
| end_time DATE, | |
| category VARCHAR2(5), | |
| code VARCHAR2(5), | |
| flag VARCHAR2(1) | |
| ); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:00', 'HH24:MI'), to_date('08:30', 'HH24:MI'), 'A', '#1', 'O'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:10', 'HH24:MI'), to_date('08:20', 'HH24:MI'), 'A', '#2', 'X'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:40', 'HH24:MI'), to_date('09:00', 'HH24:MI'), 'A', '#3', 'O'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:35', 'HH24:MI'), to_date('08:45', 'HH24:MI'), 'A', '#4', 'X'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:55', 'HH24:MI'), to_date('09:05', 'HH24:MI'), 'A', '#5', 'O'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('09:05', 'HH24:MI'), to_date('09:15', 'HH24:MI'), 'A', '#6', 'O'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:10', 'HH24:MI'), to_date('08:20', 'HH24:MI'), 'A', '#7', 'O'); | |
| INSERT INTO t_intervals(begin_time, end_time, category, code, flag) VALUES (to_date('08:10', 'HH24:MI'), to_date('08:25', 'HH24:MI'), 'A', '#8', 'X'); | |
| INSERT /*+ APPEND */ INTO t_intervals(begin_time, end_time, category, code, flag) SELECT i.begin_time + 10 / (24 * 60) begin_time, i.end_time + 10 / (24 * 60) end_time, 'B', i.code, i.flag FROM t_intervals i; | |
| COMMIT; | |
| WITH | |
| joined_intervals | |
| AS ( | |
| SELECT | |
| i.category, | |
| i.flag, | |
| MIN(i.begin_time) begin_time, | |
| MAX(i.end_time) end_time | |
| FROM | |
| ( | |
| SELECT | |
| i.category, | |
| i.flag, | |
| i.begin_time, | |
| i.end_time, | |
| MAX(i.group_1) OVER(PARTITION BY i.category, i.flag ORDER BY i.begin_time ASC) group_2 | |
| FROM | |
| ( | |
| SELECT | |
| i.category, | |
| i.flag, | |
| i.begin_time, | |
| 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, i.flag ORDER BY i.begin_time ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AND COALESCE(MAX(i.end_time) OVER(PARTITION BY i.category, i.flag 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 i.category, i.flag ORDER BY i.begin_time ASC) IS NULL | |
| THEN | |
| row_number() OVER(PARTITION BY i.category, i.flag ORDER BY i.begin_time ASC) | |
| ELSE | |
| -1 | |
| END group_1 | |
| FROM | |
| t_intervals i | |
| ) i | |
| ) i | |
| GROUP BY | |
| i.category, | |
| i.flag, | |
| i.group_2 | |
| ), | |
| moments | |
| AS ( | |
| SELECT | |
| m.time, | |
| LEAD(m.time, +1) OVER (PARTITION BY m.category ORDER BY m.time) next_time, | |
| m.category, | |
| m.flag | |
| FROM | |
| ( | |
| ( | |
| SELECT | |
| i.begin_time time, | |
| i.category, | |
| i.flag | |
| FROM | |
| joined_intervals i | |
| ) UNION ( | |
| SELECT | |
| i.end_time time, | |
| i.category, | |
| i.flag | |
| FROM | |
| joined_intervals i | |
| ) | |
| ) m | |
| ), | |
| split_intervals | |
| AS ( | |
| SELECT | |
| m.time begin_time, | |
| m.next_time end_time, | |
| i.category, | |
| i.flag | |
| FROM | |
| moments m | |
| JOIN | |
| joined_intervals i | |
| ON | |
| m.category = i.category | |
| AND i.begin_time <= m.time AND m.time < i.end_time | |
| ), | |
| match_intervals | |
| AS ( | |
| SELECT | |
| o.begin_time, | |
| o.end_time, | |
| o.category | |
| FROM | |
| ( | |
| SELECT | |
| i.* | |
| FROM | |
| split_intervals i | |
| WHERE | |
| i.flag = 'O' | |
| ) o | |
| JOIN | |
| ( | |
| SELECT | |
| i.* | |
| FROM | |
| split_intervals i | |
| WHERE | |
| i.flag = 'X' | |
| ) x | |
| ON | |
| o.begin_time = x.begin_time AND o.end_time = x.end_time | |
| AND o.category = x.category | |
| ) | |
| SELECT | |
| * | |
| FROM | |
| match_intervals; | |
| SELECT | |
| i.category, | |
| MIN(i.begin_time) begin_time, | |
| MAX(i.end_time) end_time | |
| FROM | |
| ( | |
| SELECT | |
| i.category, | |
| 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, | |
| 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 i.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 | |
| match_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