Merging intervals in one pass in SQL

前端 未结 4 755
轻奢々
轻奢々 2020-12-06 13:02

Let\'s say I have a table with two columns: start and end, both integers, and the table is ordered by the first, then second column. Each row repr

4条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-06 13:55

    Well, here is a solution that works in MySQL (I don't know if it will work in SQlite). I think, but cannot prove, that is O(n) (discarding the time it takes to sort the events table initially, i.e. if it is already sorted as I think the question states.)

    > 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)
    

提交回复
热议问题