2017-09-20 36 views
1

由于SQL Server 2008的兼容性问题,我试图实现下面的结果,但没有ROWS BETWEEN函数。您的帮助将不胜感激。更新以前行的开始日期和结束日期(无ROWS BETWEEN)

这是一个重新的

updating start and end dates of previous rows

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 

解决方案:

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 

亲切的问候 d

回答

0

我不是适用于业务规则明确中间的“合同”,但这里是一个尝试:

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 cte1 as (
    select 
     id 
     , contract 
     , StartDate 
     , EndDate 
     , row_number() over(partition by id order by contract DESC, StartDate DESC) as rn 
     , min(contract) over(partition by id) as min_contract 
     , max(contract) over(partition by id) as max_contract 
    from @table 
    ) 
, cte2 as (
    select 
      cte1.id 
      , cte1.contract 
      , cte1.StartDate 
      , case when cte1.contract = min_contract then ca.startdate 
       when cte1.contract = max_contract then '99991231' 
       else cte1.startdate 
      end NewEndDate 
    from cte1 
    cross apply (select startdate from cte1 t2 where cte1.id=t2.id and t2.rn = 1) ca 
    ) 
select 
* 
from cte2 
order by id, contract, StartDate 


    id contract StartDate NewEndDate 
------ ---------- ------------ ------------- 
    1000   1 31.08.2017 14.09.2017 
    1000   2 15.09.2017 15.09.2017 
    1000   2 16.09.2017 16.09.2017 
    1000   3 14.09.2017 31.12.9999 

见:http://rextester.com/YRYLR75136

相关问题