SQL Server 重叠日期范围(其他解决方案似乎无法满足我的要求)

问题描述 投票:0回答:1

多年来一直在努力采用非光标风格的方法来解决这个问题,但从未深入了解,所以我想我会问自己的问题。 我已经用谷歌搜索了这个问题,尝试了一些其他解决方案,但它们似乎总是不太适合我的要求,所以就在这里。

样本数据。

    DECLARE @SourceData TABLE
(
    ReferralKey         INT NOT NULL
    ,PersonID           INT NOT NULL
    ,ReferralStartDate  DATETIME NOT NULL --Time Element Doesn't Matter so could use DATE
    ,ReferralEndDate    DATETIME NULL --Time Element Doesn't Matter so could use DATE
    ,EpisodeKey         INT NULL  -- What I want to populate at the end
);

INSERT INTO @SourceData
(
    ReferralKey,
    PersonID,
    ReferralStartDate,
    ReferralEndDate
)
VALUES
(1,5, '2007-12-03', '2011-08-26'),  -- Closed Referral
(2,5, '2013-05-02', NULL),          -- Currently Open Referral
(3,5, '2013-05-03', NULL),          -- Currently Open Referral
(4,5, '2013-05-03', '2016-01-01'), -- Same date start, different referral
(5,30, '2006-10-02', '2011-01-16'),
(6,30, '2011-01-17', '2012-08-12'),
(8,30, '2012-08-13', NULL),
(8,66, '2007-09-24', NULL),
(9,66, '2007-09-24', NULL)
;

SELECT * FROM @SourceData

我的要求是,如果日期范围重叠或与第二天相邻,则将数据返回到情节中。

预期结果:

人员ID 推荐开始日期 推荐结束日期
5 2007-12-03 2011-08-26'
5 2013-05-02
30 2006-10-02
66 2007-09-24

希望我已经提供了足够的内容让人们尝试一下。就像我说的,这是一个挑战,我们长期运行查询来尝试构建这些集合。

sql sql-server common-table-expression window-functions overlap
1个回答
0
投票
select PersonID, 
    min(ReferralStartDate) as ReferralStartDate, nullif(max(ReferralEndDate), '9999-12-30') as ReferralEndDate
from (
    select ReferralKey, PersonID, ReferralStartDate, coalesce(ReferralEndDate, '9999-12-30') as ReferralEndDate, 
        sum(tomerge) over(partition by PersonID order by ReferralStartDate, ReferralEndDate) as grp
    from (
        select 
            ReferralKey, PersonID, ReferralStartDate, ReferralEndDate, 
            case when
                ReferralStartDate
                <=
                lag(max_so_far) over(partition by PersonID order by ReferralStartDate, ReferralEndDate) + 1         
                then 0 else 1 end as tomerge
        from (
            select ReferralKey, PersonID, ReferralStartDate, ReferralEndDate, 
                max( coalesce(ReferralEndDate, '9999-12-30') ) over(partition by PersonID order by ReferralStartDate, ReferralEndDate)
                as max_so_far
            from @SourceData
        ) d1
    ) d2
) d3
group by PersonID, grp
order by PersonID, ReferralStartDate
;

https://dbfiddle.uk/j4AboS6R

© www.soinside.com 2019 - 2024. All rights reserved.