更新前一行的开始和结束日期

时间:2017-09-13 12:45:06

标签: sql loops tsql stored-procedures

这个例子比根据新记录的开始日期更新以前的记录有点棘手。我希望你能帮忙。

ID 1000(有很多ID&我们需要分区吗?)有一个初始开始日期。

该ID与另一份合同相关联。因此,第一份合同的结束日期是第二份合同的开始日期。请注意,第二份合同可能会或可能不会在未来注明日期。

但是,在第二份合同开始之前,该ID可能会与另一份合同挂钩。所以第二份合同变得无效。第三个合同现在优先,第一个合同的结束日期需要更改为第三个合同的开始日期。第二份合同保持显示开始和结束日期相同。

有关如何使用T-SQL实现此目的的任何想法?

import my_project.models

提前谢谢。

亲切的问候 d

1 个答案:

答案 0 :(得分:1)

这适用于样本数据,但如果可能有多于1个合同无效连续,则会失败。

declare @table table (id int, contract int, StartDate date, EndDate date)
insert into @table
values
(1000,1,'20170831',NULL),
(1000,2,'20170916',NULL),
(1000,3,'20170914',NULL)

;with cte as(
select 
    id
    ,contract
    ,StartDate
    ,EndDate
    ,NewEndDate = case when StartDate > lead(StartDate) over (partition by id order by contract) then StartDate else  lead(StartDate) over (partition by id order by contract) end
from @table t),

cte2 as(
select
    id
    ,contract
    ,StartDate
    ,EndDate
    ,NewEndDate = case when NewEndDate = Lead(NewEndDate) over (partition by id order by contract) then Lead(StartDate,2) over (partition by id order by contract) else NewEndDate end 
from
    cte
)


update cte2
set EndDate = NewEndDate

select * from @table

编辑99 NULL并在行中空出

declare @table table (id int, contract int, StartDate date, EndDate date)
insert into @table
values
(1000,1,'20170831',NULL),
(1000,2,'20170916',NULL),
(1000,2,'20170915',NULL),
(1000,3,'20170914',NULL)

;with cte as(
select 
    id
    ,contract
    ,StartDate
    ,EndDate
    ,NewEndDate =min(StartDate) over (partition by id order by contract ROWS BETWEEN 1 FOLLOWING AND 99 FOLLOWING )
from    
    @table),

cte2 as(
select
    id
    ,contract
    ,StartDate
    ,EndDate
    ,NewEndDate = isnull(case when NewEndDate = lag(NewEndDate) over (partition by id order by contract) then StartDate else NewEndDate end,'99991231')

from
    cte)

update cte2
set EndDate = NewEndDate

select * from @table