Merge overlapping date intervals

后端 未结 7 981
不知归路
不知归路 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 17:00

    Try this

    ;WITH T1 AS
    (
        SELECT d1, d2, ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS R
        FROM @T
    ), NUMS AS
    (
        SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS R
        FROM T1 A
        CROSS JOIN T1 B
        CROSS JOIN T1 C
    ), ONERANGE AS 
    (
        SELECT DISTINCT DATEADD(DAY, ROW_NUMBER() OVER(PARTITION BY T1.R ORDER BY (SELECT 0)) - 1, T1.D1) AS ELEMENT
        FROM T1
        CROSS JOIN NUMS
        WHERE NUMS.R <= DATEDIFF(DAY, d1, d2) + 1
    ), SEQUENCE AS
    (
        SELECT ELEMENT, DATEDIFF(DAY, '19000101', ELEMENT) - ROW_NUMBER() OVER(ORDER BY ELEMENT) AS rownum
        FROM ONERANGE
    )
    SELECT MIN(ELEMENT) AS StartDate, MAX(ELEMENT) as EndDate
    FROM SEQUENCE
    GROUP BY rownum
    

    The basic idea is to first unroll the existing data, so you get a separate row for each day. This is done in ONERANGE

    Then, identify the relationship between how dates increment and the way the row numbers do. The difference remains constant within an existing range/island. As soon as you get to a new data island, the difference between them increases because the date increments by more than 1, while the row number increments by 1.

提交回复
热议问题