编写 SQL 查询以识别重叠的日期行

Writing a TSQL query to idenfity overlapping date rows

我有一个 table 每个员工有多行。这些行中的每一行都有 staff_id、start_date 和 end_date。每个员工,如果任何 start_date 位于不同行的 start_date 和 end_date 之间,或者如果任何 end_date 位于 start_date 和 end_date 之间] 不同的行,那么我必须将这些记录标记为相同。 我怎样才能做到这一点?我尝试过交叉应用,因为我认为这样做会做笛卡尔积(比较每一行),而且我也尝试过 temp tables。但我还没有让这些工作。 这是一些虚拟数据:

if exists (select  * from tempdb.dbo.sysobjects o    where o.xtype in ('U')  and o.id = object_id(N'tempdb..#staff_records')
) DROP TABLE #staff_records;

create table #staff_records
(
staff_id varchar(max),
start_date datetime,
end_date datetime
)

insert #staff_records values('AA-22','2/1/15','2/4/15')
insert #staff_records values('AA-22','2/5/15','2/6/15')
insert #staff_records values('AA-22','2/9/15','2/13/15')
insert #staff_records values('AA-22','2/4/15','2/16/15')
insert #staff_records values('AA-22','1/25/15','2/2/15')
insert #staff_records values('BB-22','2/1/15','3/1/15')
insert #staff_records values('BB-22','3/1/15','4/1/15')

select * from #staff_records order by staff_id, start_date desc

以下是否适合您的情况?

declare @staff_records table
(
tmpKey int identity(1,1),
staff_id varchar(max),
start_date datetime,
end_date datetime
)

insert @staff_records values('AA-22','2/1/15','2/4/15')
insert @staff_records values('AA-22','2/5/15','2/6/15')
insert @staff_records values('AA-22','2/9/15','2/13/15')
insert @staff_records values('AA-22','2/4/15','2/16/15')
insert @staff_records values('AA-22','1/25/15','2/2/15')
insert @staff_records values('BB-22','2/1/15','3/1/15')
insert @staff_records values('BB-22','3/1/15','4/1/15')

select * from @staff_records

select * 
from @staff_records t1
where exists
(
select 1 from @staff_records t2 
where t2.staff_id = t1.staff_id and t2.tmpKey <> t1.tmpKey
    and (t2.start_date between t1.start_date and t1.end_date OR t2.end_date between t1.start_date and t1.end_date)
)

如果您不想标记 start_date 与之前的 end_date 相同的记录,则可以是:

SELECT a.*
FROM staff_records AS a
JOIN staff_records AS b
ON a.staff_id = b.staff_id 
AND a.start_date < b.end_date
AND b.start_date < a.end_date

绘制时间线:

a                s----------e
b                        s----------------e

WHERE 检查它们是否重叠,但不会标记 start_date 和 end_date 是否相等。如果您确实想标记 start_date 和 end_date 相等的行(并且您的行有一个 ID 列),最后两行将更改为:

AND a.ID > b.ID
AND a.start_date <= b.end_date
AND b.start_date <= a.end_date 


a                          s----------e
b         s----------------e