【问题标题】:Merging intervals with MySQL与 MySQL 合并间隔
【发布时间】:2012-01-15 02:29:15
【问题描述】:

我需要一些帮助来合并重叠区间。

我有这张桌子:

id 开始 结束 1 15:30:00 16:20:00 2 10:00:00 13:00:00 3 15:00:00 16:09:00 4 11:00:00 14:00:00 5 16:20:00 16:30:00

SQL:

CREATE TABLE `intervals` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `start` time NOT NULL,
  `end` time NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `intervals` (`start`, `end`) VALUES
('15:30:00', '16:20:00'),
('10:00:00', '13:00:00'),
('15:00:00', '16:09:00'),
('11:00:00', '14:00:00'),
('16:20:00', '16:30:00');

我想要这样的输出:

id 开始 结束 2 10:00:00 14:00:00 3 15:00:00 16:30:00

只有开始和结束时间很重要; ID列基本可以忽略。

PHP https://stackoverflow.com/a/4347215/1085872 有类似的实现(直到第 2 步),但我只需要使用 MySQL 实现合并。

【问题讨论】:

  • 请注意,一些应该合并的范围(例如示例中的 ID 3 和 5)本身不会重叠。要合并它们,您需要“重叠”关系的传递闭包。在 SQL 中计算闭包通常很难甚至是不可能的。为什么要限制 SQL 解决方案?
  • 同意,使用编程语言计算区间更容易。
  • 找到了有效的 SQL 解决方案 - 这是stackoverflow.com/questions/8451925/…的最佳答案

标签: mysql merge overlapping intervals


【解决方案1】:

试试这个 -

SELECT MIN(i.start) start, MAX(i.end) end FROM
  (
    SELECT @a:=@a + 1 a, t1.start, GREATEST(t1.end, t2.end) AS end
    FROM (SELECT @a := 0) t, intervals t1
    JOIN intervals t2 ON t1.id <> t2.id and t1.start >= t2.start and t1.start < t2.end
  ) p
  JOIN intervals i
     ON (i.start BETWEEN p.start AND p.end) OR (i.end BETWEEN p.start AND p.end)
  GROUP BY p.a;

+----------+----------+
| start    | end      |
+----------+----------+
| 10:00:00 | 14:00:00 |
| 15:00:00 | 16:30:00 |
+----------+----------+

查询基于此解决方案 - http://www.artfulsoftware.com/infotree/queries.php#807

在您的数据上进行测试。

【讨论】:

  • 我对一组更复杂的重叠数据进行了尝试,但失败了。例如 1-4,2-5,3-6,10-11 失败。
猜你喜欢
  • 2021-01-19
  • 1970-01-01
  • 2019-06-22
  • 2012-02-18
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多