当前位置:  开发笔记 > 后端 > 正文

在SQL中一次合并间隔

如何解决《在SQL中一次合并间隔》经验,为你挑选了1个好方法。

假设我有一个包含两列的表:startend两个整数,并且表由第一列和第二列排序.每行代表一个间隔.

我需要的是合并间隔表:所有重叠或相邻的间隔都吞噬成一个.

它可以用JOIN查询构造,但是行数是二次的,在我的情况下是400万行(我决定编写这个问题,因为查询仍在运行).

它也可以在一次通过中完成,通过遍历每一行并跟踪最大结束时间 - 但是如何在标准SQL中执行此操作或等效操作?在SQL中有没有 O(n)方法呢?我现在正在使用SQLite; 特定于SQLite的解决方案也可以帮助我解决这个问题.

从答案相关的问题(1,2,3,4,5,6,7,8,9)我不能告诉它是否是可能的.

你能?



1> gcbenison..:

好吧,这是一个适用于MySQL的解决方案(我不知道它是否适用于SQlite).我认为,但无法证明,那就是O(n)(丢弃最初对事件表进行排序所花费的时间,即它是否已按照我认为的问题进行排序.)

> SELECT * from events;
+-------+-----+
| start | end |
+-------+-----+
|     1 |   9 |
|     5 |   8 |
|     8 |  11 |
|    11 |  13 |
|    17 |  25 |
|    18 |  26 |
|    33 |  42 |
|    59 |  81 |
|    61 |  87 |
|    97 | 132 |
|   105 | 191 |
|   107 | 240 |
|   198 | 213 |
|   202 | 215 |
+-------+-----+
14 rows in set (0.00 sec)


SET @interval_id = 0;
SET @interval_end = 0;

SELECT
  MIN(start) AS start,
  MAX(end) AS end
  FROM
    (SELECT
       @interval_id := IF(start > @interval_end,
                          @interval_id + 1,
                          @interval_id) AS interval_id,
       @interval_end := IF(start < @interval_end,
                           GREATEST(@interval_end, end),
                           end) AS interval_end,
       events.*
     FROM events
     ORDER BY start,end) tmp
  GROUP BY interval_id;

+-------+------+
| start | end  |
+-------+------+
|     1 |   13 |
|    17 |   26 |
|    33 |   42 |
|    59 |   87 |
|    97 |  240 |
+-------+------+
5 rows in set (0.00 sec)

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有