【发布时间】:2022-01-18 12:30:06
【问题描述】:
| ID | EmployeeId | ProjectId | StartDate | EndDate |
|---|---|---|---|---|
| 1 | 1 | 100 | 01-04-2019 | 30-04-2019 |
| 2 | 1 | 100 | 01-05-2019 | 31-05-2019 |
| 3 | 1 | 100 | 01-12-2019 | 31-12-2019 |
| 4 | 1 | 100 | 01-01-2020 | 31-01-2020 |
| 5 | 2 | 200 | 01-01-2019 | 31-01-2019 |
| 6 | 2 | 200 | 01-02-2019 | 28-02-2019 |
| 7 | 2 | 200 | 01-04-2019 | 28-04-2019 |
| 8 | 2 | 200 | 01-05-2019 | 31-05-2019 |
| 9 | 2 | 200 | 01-06-2019 | 30-06-2019 |
| 10 | 3 | 100 | 01-08-2019 | 31-08-2019 |
| 11 | 3 | 100 | 01-09-2019 | 30-09-2019 |
| 12 | 3 | 200 | 01-10-2019 | 31-10-2019 |
| 13 | 3 | 200 | 01-11-2019 | 30-11-2019 |
| 14 | 3 | 300 | 01-12-2019 | 31-12-2019 |
| 15 | 3 | 300 | 01-01-2020 | 31-01-2020 |
| 16 | 3 | 300 | 01-02-2020 | 29-02-2020 |
预期输出
| EmployeeId | ProjectId | StartDate | EndDate |
|---|---|---|---|
| 1 | 100 | 01-04-2019 | 31-05-2019 |
| 1 | 100 | 01-12-2019 | 31-01-2020 |
| 2 | 200 | 01-01-2019 | 28-02-2019 |
| 2 | 200 | 01-04-2019 | 28-04-2019 |
| 2 | 200 | 01-05-2019 | 30-06-2019 |
| 3 | 100 | 01-08-2019 | 30-09-2019 |
| 3 | 200 | 01-10-2019 | 30-11-2019 |
| 3 | 300 | 01-12-2019 | 29-02-2020 |
我试图找到当前行的结束日期是结束日期+1是下一行的开始日期,如果它是连续的,没有任何间隙,那么需要选择上一行的开始日期和当前行的结束日期。
;with MyCTE as
(
select mt.EmployeeId, mt.StartDate, mt.EndDate, ROW_NUMBER() over (order by ID) as RowNum
from #Employees mt
)
select c1.employeeId, case when c2.employeeId is null then c1.StartDate else dateadd(dd,1, c2.EndDate) end as StartDate,
c1.EndDate
from MyCTE c1
left join MyCTE c2
on C1.employeeId=c2.employeeId and
--and dateadd(dd,1,c1.startdate)
c1.RowNum = c2.RowNum +1
【问题讨论】:
-
这听起来像是一个非常典型的间隙和孤岛问题。这种查询的例子有数百个,堆栈溢出,互联网上可能有数千个。
-
这是一篇特别好的文章,它对连续的日期进行分组,就像您在这里尝试做的那样。 sqlservercentral.com/articles/…
标签: sql-server date datetime