根据日期间隔查询链接在一起的记录

Jus*_*ork 4 sql-server sql-server-2012

我在 SQL Server 2012 中有一个具有以下简化架构的表,我需要定义一个查询来获取最新的记录,然后返回它们之间间隔少于 30 天的记录链。一旦出现超过 30 天的差距,链条就会被打破,不再继续。重叠应该延续链条。有没有办法在不诉诸缓慢和递归的情况下解决这个问题?

架构

ID          (int)
Arrival     (datetime)
Departure   (datetime)
Run Code Online (Sandbox Code Playgroud)

样本数据

ID Arrival       Departure
1 2009-04-19    2009-04-28 
2 2009-04-27    2009-05-21 
3 2009-06-11    2009-07-01 
4 2009-07-19    2009-07-24 
5 2004-04-19    2004-04-21 
6 2009-02-28    2009-03-05
Run Code Online (Sandbox Code Playgroud)

所需查询结果

ID Arrival       Departure
4 2009-07-19    2009-07-24 
3 2009-06-11    2009-07-01
2 2009-04-27    2009-05-21 
1 2009-04-19    2009-04-28 
Run Code Online (Sandbox Code Playgroud)

Pau*_*ite 7

以下解决方案 ( SQL Fiddle ) 使用SQL Server 2012LAST_VALUE函数

SELECT
    MaxDiff.ID,
    MaxDiff.Arrival,
    MaxDiff.Departure
FROM 
(
    -- Maximum difference encountered so far
    SELECT *,
        MaxDiff = LAST_VALUE(Diff.Diff)  OVER (
            ORDER BY Diff.Departure DESC 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
    FROM 
    (
        -- Difference between departure and prior arrival
        SELECT *,
            Diff = 
                ISNULL(DATEDIFF(DAY, r.Departure,
                        LAST_VALUE(r.Arrival) OVER (
                            ORDER BY r.Departure DESC 
                            ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)), 0)
        FROM dbo.Records AS r
    ) AS Diff
) AS MaxDiff
WHERE
    MaxDiff.MaxDiff <= 30
ORDER BY
    MaxDiff.Departure DESC;
Run Code Online (Sandbox Code Playgroud)

结果:

????????????????????????????????
? ID ?  Arrival   ? Departure  ?
????????????????????????????????
?  4 ? 2009-07-19 ? 2009-07-24 ?
?  3 ? 2009-06-11 ? 2009-07-01 ?
?  2 ? 2009-04-27 ? 2009-05-21 ?
?  1 ? 2009-04-19 ? 2009-04-28 ?
????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

执行计划:

方案一