调整SQL 2008的开始和结束日期

时间:2018-07-08 10:05:31

标签: sql sql-server-2008 date comparison

我有一个ID的以下数据,其中包含开始日期和结束日期及其费用

ID    Start Date    End date    Cost
121   06/06/2016    17/09/2017  157.5
121   21/08/2016    16/10/2016  247.5
121   20/08/2017    17/09/2017  450

输出应该是这样

ID    Start Date    End date      Cost
121   06/06/2016    20/08/2016    157.5
121   21/08/2016    16/10/2016    247.5
121   17/10/2016    19/08/2017    157.5
121   20/08/2017    17/09/2017    450

上一条记录应在下一条记录的基础上结束并显示相关金额。有人可以帮忙在SQL 2008中实现这一点。谢谢。

1 个答案:

答案 0 :(得分:1)

这些类型的时间重叠问题具有挑战性-而且在没有lead()lag()的情况下更是如此。

该想法是获取每个日期的信息,并将其重新组合在一起。在此过程中,我们需要跟踪不同价格的“进”和“出”。在SQL Server 2008中,这自由地使用了apply

此查询解决了您的问题:

with t as (
      select id, cast(sdate as date) as sdate, cast(edate as date) edate, cost
      from (values (121, '2016-06-06', '2017-09-17', 157.5),
                   (121, '2016-08-21', '2016-10-16', 247.5),
                   (121, '2017-08-20', '2017-09-17', 450)
           ) v(id, sdate, edate, cost)
     ),
     dates as (
      select id, dte, cost, sum(inc) as inc
      from ((select id, sdate as dte, cost, 1 as inc
             from t
            ) union all
            (select id, dateadd(day, 1, edate), NULL, -1 as inc
             from t
            )
           ) d
      group by id, dte, cost
     ),
     d as (
      select dates.*, d.suminc
      from dates outer apply
           (select sum(d.inc) as suminc
            from dates d
            where d.id = dates.id and d.dte <= dates.dte
           ) d
     )
select d.id, d.dte as start_date,
       dateadd(day, -1, dnext.dte) as end_dte,
       coalesce(d.cost, dprev.cost) as cost
from d cross apply
     (select top (1) dnext.*
      from d dnext
      where dnext.id = d.id and dnext.dte > d.dte
      order by dnext.dte
     ) dnext outer apply
     (select top (1) dprev.*
      from d dprev
      where dprev.id = d.id and dprev.dte < d.dte and dprev.suminc = d.suminc
      order by dprev.dte desc
     ) dprev
order by d.dte;

Here是一个学期。