更新前一行的开始和结束日期(没有ROWS BETWEEN)

时间:2017-09-20 14:34:41

标签: sql sql-server-2008 tsql

由于与SQL Server 2008的兼容性问题,我试图在没有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

1 个答案:

答案 0 :(得分: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