Merge overlapping date intervals

后端 未结 7 1001
不知归路
不知归路 2020-11-27 16:16

Is there a better way of merging overlapping date intervals?
The solution I came up with is so simple that now I wonder if someone else has a better idea of how this cou

7条回答
  •  时光说笑
    2020-11-27 16:52

    The idea is to simulate the scanning algorithm for merging intervals. My solution makes sure it works across a wide range of SQL implementations. I've tested it on MySQL, Postgres, SQL-Server 2017, SQLite and even Hive.

    Assuming the table schema is the following.

    CREATE TABLE t (
      a DATETIME,
      b DATETIME
    );
    

    We also assume the interval is half-open like [a,b).

    When (a,i,j) is in the table, it shows that there are j intervals covering a, and there are i intervals covering the previous point.

    CREATE VIEW r AS 
    SELECT a,
           Sum(d) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS i,
           Sum(d) OVER (ORDER BY a ROWS UNBOUNDED PRECEDING) AS j
    FROM  (SELECT a, Sum(d) AS d
           FROM   (SELECT a,  1 AS d FROM t
                   UNION ALL
                   SELECT b, -1 AS d FROM t) e
           GROUP  BY a) f;
    

    We produce all the endpoints in the union of the intervals and pair up adjacent ones. Finally, we produce the set of intervals by only picking the odd-numbered rows.

    SELECT a, b
    FROM (SELECT a,
                 Lead(a)      OVER (ORDER BY a) AS b,
                 Row_number() OVER (ORDER BY a) AS n
          FROM   r
          WHERE  j=0 OR i=0 OR i is null) e
    WHERE  n%2 = 1;
    

    I've created a sample DB-fiddle and SQL-fiddle. I also wrote a blog post on union intervals in SQL.

提交回复
热议问题