Assuming your data is not very off, you can use lag()
:
with toupdate as (
select t.*,
lag(enddate) over (partition by employee order by startdate) as prev_enddate
from t
) t
update toupdate
set startdate = dateadd(day, 1, prev_enddate)
where startdate <> dateadd(day, 1, prev_enddate);
If your data has lots of really complicated overlaps, then this gets a bit trickier. Basically, you want to keep the end dates and use them to calculate the start dates -- for all but the first row:
with toupdate as (
select t.*,
lag(enddate) over (partition by employee order by enddate) as prev_enddate,
row_number() over (partition by employee order by startdate) as seqnum
from t
) t
update toupdate
set startdate = dateadd(day, 1, prev_enddate)
where seqnum <> 1 and
startdate <> dateadd(day, 1, prev_enddate);
You need seqnum
(or something similar) because you are not guaranteed that the earliest start date has the earliest end date in this situation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…