MySQL find intersection of overlaps -


i have database table containing events:

create table events event varchar(32) ,down_time timestamp ,up_time timestamp ,id int unsigned not null auto_increment key ,index(event(16)) );  insert events(event, down_time, up_time) values ('e1', '2015-01-01 00:00:04', '2015-01-01 00:00:08'), ('e2', '2015-01-01 00:00:05', '2015-01-01 00:00:06'), ('e3', '2015-01-01 00:00:02', '2015-01-01 00:00:09'), ('e4', '2015-01-01 00:00:01', '2015-01-01 00:00:07'), ('e5', '2015-01-01 00:00:03', '2015-01-01 00:00:10');  select * events;  +-------+---------------------+---------------------+----+ | event | down_time           | up_time             | id | +-------+---------------------+---------------------+----+ | e1    | 2015-01-01 00:00:04 | 2015-01-01 00:00:08 |  1 | | e2    | 2015-01-01 00:00:05 | 2015-01-01 00:00:06 |  2 | | e3    | 2015-01-01 00:00:02 | 2015-01-01 00:00:09 |  3 | | e4    | 2015-01-01 00:00:01 | 2015-01-01 00:00:07 |  4 | | e5    | 2015-01-01 00:00:03 | 2015-01-01 00:00:10 |  5 | +-------+---------------------+---------------------+----+ 5 rows in set (0.00 sec)      1   2   3   4   5   6   7   8   9   10     |   |   |   |   |   |   |   |   |   |     |   |   |   |-------e1------|   |   |     |   |   |   |   |-e2|   |   |   |   |     |   |--------------e3-----------|   |     |----------e4-----------|   |   |   |     |   |   |-------------e5------------| 

i identify if events overlap @ 1 time. in above intersect here (e2):

overlap |overlap_down_time   | overlap_up_time     | overlap_duration 1       |2015-01-01 00:00:05 | 2015-01-01 00:00:06 | 00:00:01 

i can find overlaps between pairs of events using query not sure how include events ..many in advance !

select   e1.event event1_name,   e1.down_time event1_down_time,   e1.up_time event1_up_time,   timediff(e1.up_time, e1.down_time) event1_duration,    e2.event event2_name,   e2.down_time event2_down_time,   e2.up_time event2_up_time,   timediff(e2.up_time, e2.down_time) event1_duration,    greatest(e1.down_time,e2.down_time) overlap_down_time,    least(e1.up_time,e2.up_time) overlap_up_time,   timediff( least(e1.up_time,e2.up_time),   greatest(e1.down_time,e2.down_time) ) overlap_duration   events e1  inner join events e2 on e1.id < e2.id  ( e2.down_time <= e1.up_time )  ,  ( e2.up_time >= e1.down_time ); 

the solutions proposed below not appear cover case event occurs twice within overall timeframe ..as happens e2 below:

1   2   3   4   5   6   7   8   9   10 |   |   |   |-------e1------|   |   | |   |   |---e2--|   |-------e2------|    |   |-------------e3------------|   | |----------e4-----------|   |   |   |  insert events(event, down_time, up_time) values     ('e1', '2015-01-01 00:00:04', '2015-01-01 00:00:08'),     ('e2', '2015-01-01 00:00:03', '2015-01-01 00:00:05'),     ('e2', '2015-01-01 00:00:06', '2015-01-01 00:00:10'),     ('e3', '2015-01-01 00:00:02', '2015-01-01 00:00:09'),     ('e4', '2015-01-01 00:00:01', '2015-01-01 00:00:07'); 

i have been able identify intersect using 2 stage query:

create view overlap1 select concat(a.event,'-', b.event) overlaps, greatest(a.down_time,b.down_time) downtime,  least(a.up_time,b.up_time) uptime, time_to_sec(timediff( least(a.up_time,b.up_time),     greatest(a.down_time,b.down_time))) duration  events  join events b  on  a.event < b.event      , (a.event = 'e1' or a.event = 'e2' or a.event = 'e3' or a.event = 'e4')     , (b.event = 'e1' or b.event = 'e2' or b.event = 'e3' or b.event = 'e4')    ( a.down_time <= b.up_time ) ,     ( a.up_time >= b.down_time );  select * overlap1; +----------+---------------------+---------------------+----------+ | overlaps | downtime            | uptime              | duration | +----------+---------------------+---------------------+----------+ | e1-e2    | 2015-01-01 00:00:04 | 2015-01-01 00:00:05 |        1 | | e1-e2    | 2015-01-01 00:00:06 | 2015-01-01 00:00:08 |        2 | | e1-e3    | 2015-01-01 00:00:04 | 2015-01-01 00:00:08 |        4 | | e2-e3    | 2015-01-01 00:00:03 | 2015-01-01 00:00:05 |        2 | | e2-e3    | 2015-01-01 00:00:06 | 2015-01-01 00:00:09 |        3 | | e1-e4    | 2015-01-01 00:00:04 | 2015-01-01 00:00:07 |        3 | | e2-e4    | 2015-01-01 00:00:03 | 2015-01-01 00:00:05 |        2 | | e2-e4    | 2015-01-01 00:00:06 | 2015-01-01 00:00:07 |        1 | | e3-e4    | 2015-01-01 00:00:02 | 2015-01-01 00:00:07 |        5 | +----------+---------------------+---------------------+----------+  create view overlap2 select concat(a.overlaps,'-',b.overlaps) overlaps, greatest(a.downtime,b.downtime) downtime, least(a.uptime,b.uptime) uptime, timediff( least(a.uptime,b.uptime), greatest(a.downtime,b.downtime) ) duration  overlap1 join overlap1 b  on a.overlaps < b.overlaps , (a.overlaps = 'e1-e2' or a.overlaps = 'e3-e4') , (b.overlaps = 'e1-e2' or b.overlaps = 'e3-e4')    ( a.downtime <= b.uptime ) , ( a.uptime >= b.downtime );  select * overlap2; +-------------+---------------------+---------------------+----------+ | overlaps    | downtime            | uptime              | duration | +-------------+---------------------+---------------------+----------+ | e1-e2-e3-e4 | 2015-01-01 00:00:04 | 2015-01-01 00:00:05 | 00:00:01 | | e1-e2-e3-e4 | 2015-01-01 00:00:06 | 2015-01-01 00:00:07 | 00:00:01 | +-------------+---------------------+---------------------+----------+ 

i achieve single query if possible ..any appreciated !

following query meet requirement:

select e1.* events e1 join events e2 on e1.down_time>=e2.down_time , e1.up_time<=e2.up_time group e1.event having count(*)=(select count(*) events) 

verify result @ http://sqlfiddle.com/#!9/7c733/4


Comments