多年来一直在努力采用非光标风格的方法来解决这个问题,但从未深入了解,所以我想我会问自己的问题。 我已经用谷歌搜索了这个问题,尝试了一些其他解决方案,但它们似乎总是不太适合我的要求,所以就在这里。
样本数据。
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 | 空 |
希望我已经提供了足够的内容让人们尝试一下。就像我说的,这是一个挑战,我们长期运行查询来尝试构建这些集合。
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
;