我有一个如此定义的MySQL 5.6表:
DROP TABLE IF EXISTS `ranges`;
CREATE TABLE `ranges` (
`id` int(6) unsigned NOT NULL,
`start` datetime NOT NULL,
`end` datetime NOT NULL);
INSERT INTO `ranges` (`id`, `start`, `end`) VALUES
(1, '2017-12-16 00:00:00', '2017-12-16 04:00:00'),
(1, '2017-12-16 12:00:00', '2017-12-16 16:00:00'),
(1, '2017-12-16 03:00:00', '2017-12-16 13:00:00'),
(2, '2017-12-16 00:00:00', '2017-12-16 05:00:00'),
(2, '2017-12-16 07:00:00', '2017-12-16 14:00:00'),
(3, '2017-12-16 00:00:00', '2017-12-16 04:00:00');
我希望按ID合并重叠时间范围,并按原样保留非重叠范围。因此id 1将被折叠成单行,而id 2和3将保持原样,因为id 2的行不重叠,而id 3显然不能,因为它只有一行。结果输出应为:
1, 2017-12-16 00:00:00, 2017-12-16 16:00:00
2, 2017-12-16 00:00:00, 2017-12-16 05:00:00
2, 2017-12-16 07:00:00, 2017-12-16 14:00:00
3, 2017-12-16 00:00:00, 2017-12-16 04:00:00
我已经查看了相关问题,并在这里摆弄了解决方案:https://www.sqlservercentral.com/Forums/Topic826031-8-1.aspx。我试图通过这种尝试来调整那个不依赖于id列的解决方案:
SELECT s1.id, s1.Start,
MIN(t1.End) AS End
FROM ranges s1
INNER JOIN ranges t1 ON s1.id = t1.id AND s1.Start <= t1.End
AND NOT EXISTS(SELECT * FROM ranges t2
WHERE t1.id = t2.id AND t1.End >= t2.Start AND t1.End < t2.End)
WHERE NOT EXISTS(SELECT * FROM ranges s2
WHERE s1.id = s2.id AND s1.Start > s2.Start AND s1.Start <= s2.End)
GROUP BY s1.id
ORDER BY s1.id;
但是,只是将id添加到所有谓词中并不能给出正确的结果;它似乎忽略了不重叠的范围。由于我不明白原始查询是如何工作的,所以我宁愿出海,直到正确的咒语。谢谢!
SQLFiddle:http://sqlfiddle.com/#!9/6bf76b/1/0