Combine consecutive date ranges

前端 未结 4 538
礼貌的吻别
礼貌的吻别 2020-12-06 12:28

Using SQL Server 2008 R2,

I\'m trying to combine date ranges into the maximum date range given that one end date is next to the following start date.

The da

4条回答
  •  醉梦人生
    2020-12-06 13:26

    The strange bit you see with my use of the date '31211231' is just a very large date to handle your "no-end-date" scenario. I have assumed you won't really have many date ranges per employee, so I've used a simple Recursive Common Table Expression to combine the ranges.

    To make it run faster, the starting anchor query keeps only those dates that will not link up to a prior range (per employee). The rest is just tree-walking the date ranges and growing the range. The final GROUP BY keeps only the largest date range built up per starting ANCHOR (employmentid, startdate) combination.


    SQL Fiddle

    MS SQL Server 2008 Schema Setup:

    create table Tbl (
      employmentid int,
      startdate datetime,
      enddate datetime);
    
    insert Tbl values
    (5, '2007-12-03', '2011-08-26'),
    (5, '2013-05-02', null),
    (30, '2006-10-02', '2011-01-16'),
    (30, '2011-01-17', '2012-08-12'),
    (30, '2012-08-13', null),
    (66, '2007-09-24', null);
    
    /*
    -- expected outcome
    EmploymentId StartDate   EndDate
    5            2007-12-03  2011-08-26
    5            2013-05-02  NULL
    30           2006-10-02  NULL
    66           2007-09-24  NULL
    */
    

    Query 1:

    ;with cte as (
       select a.employmentid, a.startdate, a.enddate
         from Tbl a
    left join Tbl b on a.employmentid=b.employmentid and a.startdate-1=b.enddate
        where b.employmentid is null
        union all
       select a.employmentid, a.startdate, b.enddate
         from cte a
         join Tbl b on a.employmentid=b.employmentid and b.startdate-1=a.enddate
    )
       select employmentid,
              startdate,
              nullif(max(isnull(enddate,'32121231')),'32121231') enddate
         from cte
     group by employmentid, startdate
     order by employmentid
    

    Results:

    | EMPLOYMENTID |                        STARTDATE |                       ENDDATE |
    -----------------------------------------------------------------------------------
    |            5 |  December, 03 2007 00:00:00+0000 | August, 26 2011 00:00:00+0000 |
    |            5 |       May, 02 2013 00:00:00+0000 |                        (null) |
    |           30 |   October, 02 2006 00:00:00+0000 |                        (null) |
    |           66 | September, 24 2007 00:00:00+0000 |                        (null) |
    

提交回复
热议问题