按ID

时间:2017-12-16 23:01:34

标签: mysql sql

我有一个如此定义的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

0 个答案:

没有答案