基础上加入和将相关数据的解决方案。现在我经常使用CTE,但在它们很受欢迎之前,我们不得不考虑使用这样的东西。
select *
into ##test1
from
(
select ID = 1, CLT_NBR = 12375, IS_PRIMARY = 1, EFFECT_DATE = cast('8/13/2015' as date), END_DATE = cast('9/30/2015' as date)
union all select ID = 2, CLT_NBR = 12375, IS_PRIMARY = 1, EFFECT_DATE = cast('10/1/2015' as date), END_DATE = cast('12/31/9998' as date)
union all select ID = 3, CLT_NBR = 12375, IS_PRIMARY = 1, EFFECT_DATE = cast('7/18/2017' as date), END_DATE = cast('12/31/9998' as date)
union all select ID = 4, CLT_NBR = 12331, IS_PRIMARY = 1, EFFECT_DATE = cast('2/3/2016' as date), END_DATE = cast('7/8/2016' as date)
union all select ID = 5, CLT_NBR = 12331, IS_PRIMARY = 1, EFFECT_DATE = cast('7/9/2016' as date), END_DATE = cast('12/31/9998' as date)
) x
select * from ##test1
select t.ID, t.CLT_NBR, t.IS_PRIMARY, t.EFFECT_DATE, END_DATE = isnull(dateadd(day,-1,min(t_next.EFFECT_DATE)),'9998-12-31')
from ##test1 t
left join ##test1 t_next on t_next.CLT_NBR = t.CLT_NBR and t_next.effect_date > t.effect_date
group by t.ID, t.CLT_NBR, t.IS_PRIMARY, t.EFFECT_DATE
update t
set END_DATE = helper.END_DATE
from ##test1 t
left join
(
select t.ID, t.CLT_NBR, t.IS_PRIMARY, t.EFFECT_DATE, END_DATE = isnull(dateadd(day,-1,min(t_next.EFFECT_DATE)),'9998-12-31')
from ##test1 t
left join ##test1 t_next on t_next.CLT_NBR = t.CLT_NBR and t_next.effect_date > t.effect_date
group by t.ID, t.CLT_NBR, t.IS_PRIMARY, t.EFFECT_DATE
) helper on helper.id = t.id
select * from ##test1
drop table ##test1
为什么不降END_DATE列和使用递归CTE在查询计算它数据? –
你应该看到我的答案为sql 2008兼容版本 – DhruvJoshi
@SeanLange - 尽可能多地我也推荐这个(或者用'LEAD()')的东西,那些查询会消耗大量资源。由于这些数据通常相当静态,所以缓存结束日期通常会更好,尽管可以将其计算为列。也就是说,我绝对建议将它作为**独占**('<')上限,以便查询它不会遇到类型转换的有趣情况(即非最大值结束日期应该相同作为下一行的生效日期)。 –