我有一个包含事件的数据库表:
CREATE TABLE events
(event VARCHAR(32)
,down_time TIMESTAMP
,up_time TIMESTAMP
,id INT UNSIGNED NOT NULL AUTO_INCREMENT KEY
,INDEX(event(16))
);
1 2 3 4 5 6 7 8 9 10
| | | |-------e1------| | |
| | |---e2--| |-------e2------|
| |-------------e3------------| |
|----------e4-----------| | | |
INSERT INTO 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');
我希望找到它们相交的时间,并且能够通过组合两个查询来实现这一点。
第一次查询:
CREATE VIEW overlap1 AS
SELECT
CONCAT(a.event,'-', b.event) overlaps,
GREATEST(a.down_time,b.down_time) AS downtime,
LEAST(a.up_time,b.up_time) AS uptime,
TIME_TO_SEC(TIMEDIFF( LEAST(a.up_time,b.up_time),
GREATEST(a.down_time,b.down_time))) AS duration
FROM events a
JOIN events b
ON a.event < b.event
AND (a.event = 'e1' OR a.event = 'e2' OR a.event = 'e3' OR a.event = 'e4')
AND (b.event = 'e1' OR b.event = 'e2' OR b.event = 'e3' OR b.event = 'e4')
WHERE ( a.down_time <= b.up_time )
AND ( a.up_time >= b.down_time );
SELECT * FROM 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 AS
SELECT
CONCAT(a.overlaps,'-',b.overlaps) AS overlaps,
GREATEST(a.downtime,b.downtime) AS downtime,
LEAST(a.uptime,b.uptime) AS uptime,
TIMEDIFF( LEAST(a.uptime,b.uptime),
GREATEST(a.downtime,b.downtime) ) AS duration
FROM overlap1 a
JOIN overlap1 b
ON a.overlaps < b.overlaps
AND (a.overlaps = 'e1-e2' OR a.overlaps = 'e3-e4')
AND (b.overlaps = 'e1-e2' OR b.overlaps = 'e3-e4')
WHERE ( a.downtime <= b.uptime )
AND ( a.uptime >= b.downtime );
SELECT * FROM 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 |
+-------------+---------------------+---------------------+----------+
如果可能的话,我想使用一个查询来实现这一点。非常感谢!