根据序列位置编号创建新的开始日期和结束日期,

时间:2020-05-17 23:38:13

标签: sql sql-server tsql date gaps-and-islands

如何根据序列位置编号创建新的开始日期和结束日期:

来自

EmpNo   StartDate   EndDate     PositionNumber
832319  4/05/2020   10/05/2020  32681
832319  11/05/2020  17/05/2020  32681
832319  18/05/2020  24/05/2020  32681
832319  25/05/2020  31/05/2020  32681
832319  1/06/2020   7/06/2020   32681
832319  8/06/2020   14/06/2020  32681
832319  15/06/2020  21/06/2020  32783
832319  22/06/2020  28/06/2020  32783
832319  29/06/2020  5/07/2020   32783
832319  6/07/2020   12/07/2020  32781
832319  13/07/2020  19/07/2020  32781
832319  20/07/2020  26/07/2020  32681
832319  27/07/2020  2/08/2020   32681

要(为新的开始日期和新的结束日期创建两个新字段)

EmpNo   StartDate   EndDate     PositionNumber  NewStartDate    New EndDate
832319  4/05/2020   10/05/2020  32681   4/05/2020   14/06/2020
832319  11/05/2020  17/05/2020  32681   4/05/2020   14/06/2020
832319  18/05/2020  24/05/2020  32681   4/05/2020   14/06/2020
832319  25/05/2020  31/05/2020  32681   4/05/2020   14/06/2020
832319  1/06/2020   7/06/2020   32681   4/05/2020   14/06/2020
832319  8/06/2020   14/06/2020  32681   4/05/2020   14/06/2020
832319  15/06/2020  21/06/2020  32783   21/06/2020  5/07/2020
832319  22/06/2020  28/06/2020  32783   21/06/2020  5/07/2020
832319  29/06/2020  5/07/2020   32783   21/06/2020  5/07/2020
832319  6/07/2020   12/07/2020  32781   6/07/2020   19/07/2020
832319  13/07/2020  19/07/2020  32781   6/07/2020   19/07/2020
832319  20/07/2020  26/07/2020  32681   20/07/2020  2/08/2020
832319  27/07/2020  2/08/2020   32681   20/07/2020  2/08/2020

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我理解这是一个隔-与孤岛的问题。您希望共享相同的empNopositionNo的“相邻”行的最小和最大日期。

这里是使用窗口函数的一种方法。想法是使用lag()和累积sum()来定义组:

select 
    empNo,
    startDate,
    endDate,
    positionNumber,
    min(startDate) over(partition by empNo, positionNumber, grp) newStartDate,
    max(endDate)   over(partition by empNo, positionNumber, grp) newEndDate
from (
    select 
        t.*,
        sum(case when startDate = dateadd(day, 1, lagEndDate) then 0 else 1 end)
            over(partition by empNo, positionNumber order by endDate) grp
    from (
        select 
            t.*, 
            lag(endDate) 
                over(partition by empNo, positionNumber order by endDate) lagEndDate
        from mytable t
    ) t
) t
order by empNo, startDate

Demo on DB Fiddle

 empNo | startDate  | endDate    | positionNumber | newStartDate | newEndDate
-----: | :--------- | :--------- | -------------: | :----------- | :---------
832319 | 2020-05-04 | 2020-05-10 |          32681 | 2020-05-04   | 2020-06-14
832319 | 2020-05-11 | 2020-05-17 |          32681 | 2020-05-04   | 2020-06-14
832319 | 2020-05-18 | 2020-05-24 |          32681 | 2020-05-04   | 2020-06-14
832319 | 2020-05-25 | 2020-05-31 |          32681 | 2020-05-04   | 2020-06-14
832319 | 2020-06-01 | 2020-06-07 |          32681 | 2020-05-04   | 2020-06-14
832319 | 2020-06-08 | 2020-06-14 |          32681 | 2020-05-04   | 2020-06-14
832319 | 2020-06-15 | 2020-06-21 |          32783 | 2020-06-15   | 2020-07-05
832319 | 2020-06-22 | 2020-06-28 |          32783 | 2020-06-15   | 2020-07-05
832319 | 2020-06-29 | 2020-07-05 |          32783 | 2020-06-15   | 2020-07-05
832319 | 2020-07-06 | 2020-07-12 |          32781 | 2020-07-06   | 2020-07-19
832319 | 2020-07-13 | 2020-07-19 |          32781 | 2020-07-06   | 2020-07-19
832319 | 2020-07-20 | 2020-07-26 |          32681 | 2020-07-20   | 2020-07-26
832319 | 2020-07-27 | 2020-02-08 |          32681 | 2020-07-27   | 2020-02-08

答案 1 :(得分:0)

您要查找最小开始日期和最大结束日期吗?

select t.*,
       min(startdate) over (partition by empno, positionnumber) as new_startdate,
       min(enddate) over (partition by empno, positionnumber) as new_enddate
from t
相关问题