2017-09-13 1 views
1

이 예제는 새 레코드의 시작 날짜를 기준으로 이전 레코드를 업데이트하는 것보다 조금 까다 롭습니다. 네가 도울 수 있기를 바랐다.이전 행의 시작 날짜와 끝 날짜 업데이트

ID 1000 (ID가 많고 파티션이 필요합니까?) 초기 시작 날짜가 있습니다.

ID가 다른 계약서에 연결됩니다. 따라서 첫 번째 계약의 종료 날짜는 두 번째 계약의 시작 날짜입니다. 두 번째 계약은 미래의 날짜 일 수도 있고 아닐 수도 있습니다.

그러나 두 번째 계약이 시작되기 전에 ID가 다른 계약서에 연결될 수 있습니다. 그래서 두 번째 계약은 무효가됩니다. 이제 3 차 계약이 우선 적용되고 첫 번째 계약의 종료일을 3 차 계약의 시작 날짜로 변경해야합니다. 두 번째 계약에는 시작일과 종료일이 동일하게 유지됩니다.

T-SQL을 사용하여이를 달성하는 방법에 대한 아이디어가 있으십니까?

id  contract Start Date End Date 
1000  1  2017/08/31 9999/12/31 


id  contract Start Date End Date 
1000  1  2017/08/31 2017/09/16 
1000  2  2017/09/16 9999/12/31 

id  contract Start Date End Date 
1000  1  2017/08/31 2017/09/14 
1000  2  2017/09/16 2017/09/16 
1000  3  2017/09/14 9999/12/31 

감사합니다.

종류는 D

+0

SQL 서버의 버전은 무엇? – scsimon

+0

안녕하세요, Scsimon, SQL 2014입니다. – user3497385

답변

1

이 샘플 데이터에 대한 작동하지만, 행에 널 (null)와 무효 것 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 무효 편집

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 
+0

고맙습니다 :) null과 void 인 1 건을 넘는 계약이있을 수 있습니다. – user3497385

+0

그래서 2와 3 개의 행을 가질 수도 있습니다. 예를 들어 null과 void가됩니다. 그래서 당신이 언급 한 것처럼 납은 실패 할 것입니다. – user3497385

+0

음, 더 나은 샘플 데이터를 제공 할 수 있습니까? 왜 그냥 무효/활성 깃발을 추가하지? 이런 식으로 꽤 일반적입니다. – scsimon

관련 문제