Jon*_*oln 7 sql t-sql sql-server-2008-r2
使用SQL Server 2008 R2,
我正在尝试将日期范围组合到最大日期范围,因为一个结束日期与下一个开始日期相邻.
数据是关于不同的工作.一些员工可能已经结束了他们的工作,并在以后重新加入.那些应该算作两种不同的工作(例如ID 5).有些人有不同类型的工作,彼此追逐(结束和开始时间),在这种情况下,它应被视为一个就业(例如ID 30).
尚未结束的就业期限为无效的终止日期.
一些例子可能具有启发性:
declare @t as table (employmentid int, startdate datetime, enddate datetime)
insert into @t 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
Run Code Online (Sandbox Code Playgroud)
我一直在尝试不同的"孤岛"技术,但未能破解这一技术.
Ric*_*iwi 12
你使用日期'31211231'看到的奇怪的一点只是处理你的"无结束日期"场景的一个非常大的日期.我假设你每个员工不会有很多日期范围,所以我使用了一个简单的递归公用表表达式来组合范围.
为了使其运行更快,起始锚点查询仅保留那些不会链接到先前范围(每个员工)的日期.其余的只是树木行走的日期范围和增长范围.最终GROUP BY仅保留每个起始ANCHOR(employmentid,startdate)组合构建的最大日期范围.
MS SQL Server 2008架构设置:
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
*/
Run Code Online (Sandbox Code Playgroud)
查询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
Run Code Online (Sandbox Code Playgroud)
结果:
| 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) |
Run Code Online (Sandbox Code Playgroud)