I have a MySQL 5.6 table defined thusly:
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');
I want to merge overlapping time ranges by id and preserve non-overlapping ranges as-is. So id 1 would be collapsed into a single row, whereas ids 2 and 3 would remain as they are since id 2's rows don't overlap and id 3 obviously can't since it has only one row. The resulting output should be:
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
I've looked at related questions and fiddled with the solution here: https://www.sqlservercentral.com/Forums/Topic826031-8-1.aspx. I attempted to adapt that solution, which isn't dependent on an id column, with this attempt:
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; 
However, simply adding the id to all the predicates doesn't give the correct result; it seems to ignore the non-overlapping ranges. Since I don't understand how the original query actually works, I'm rather out to sea as far as the correct incantation. Thank you!
SQLFiddle: http://sqlfiddle.com/#!9/6bf76b/1/0