想象一下这个日期范围列表
> SELECT * FROM range_table;
+----+------------+------------+
| id | start | end |
+----+------------+------------+
| 1 | 2014-01-01 | 2014-01-15 | /* -- Not conflicting */
| 2 | 2014-01-15 | 2014-01-16 | /* -- Conflicting */
| 3 | 2014-01-15 | 2014-01-20 | /* | */
| 4 | 2014-01-15 | 2014-01-19 | /* / */
| 5 | 2014-01-24 | 2014-01-26 | /* -- Conflicting */
| 6 | 2014-01-21 | 2014-01-25 | /* / */
+----+------------+------------+
我正在尝试删除冲突的范围,并且只保留每个冲突集的第一次出现。
这是我最后应该拥有的:
+----+------------+------------+
| id | start | end |
+----+------------+------------+
| 1 | 2014-01-01 | 2014-01-15 |
| 2 | 2014-01-15 | 2014-01-16 |
| 5 | 2014-01-24 | 2014-01-26 |
+----+------------+------------+
以下是fiddle
答案 0 :(得分:1)
SELECT x.*
FROM range_table x
LEFT
JOIN range_table y
ON y.start < x.end
AND y.end > x.start
AND y.id < x.id
WHERE y.id IS NULL;
http://sqlfiddle.com/#!2/6f723/26
查询修改以适应明显修改的简要
答案 1 :(得分:0)
这是我可能的解决方案:
SELECT `id`, `start`, `end`
FROM (
SELECT
r1.id
, r1.start
, r1.end
, COUNT(DISTINCT r2.id) AS "conflicts"
, MD5(GROUP_CONCAT(DISTINCT r2.id ORDER BY r2.id)) AS "group_chksum"
FROM range_table AS r1
LEFT JOIN range_table AS r2
ON (r1.end > r2.start AND r1.start < r2.end)
GROUP BY r1.id
) AS tmp
GROUP BY group_chksum
;
我们的想法是按照范围的集合和MySQL的容忍度的优势对结果进行分组,以获取每个的结果。
我确信有更简单的