Написание запроса TSQL для идентификации перекрывающихся строк дат

У меня есть таблица с несколькими строками на одного сотрудника. Каждая из этих строк имеет staff_id, start_date и end_date. Согласно персоналу, если какая-либо начальная_дата находится между начальной_датой и конечной_датой другой строки или если какая-либо конечная_дата находится между начальной_датой и конечной_датой другой строки, тогда я должен пометить эти записи как идентичные. Как я могу это сделать? Я попытался выполнить перекрестное применение, потому что думал, что это будет декартово произведение (сравнение каждой строки), и я также пробовал временные таблицы. Но я не получил ни один из них, чтобы работать. Вот некоторые фиктивные данные:

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

person salvationishere    schedule 18.08.2015    source источник


Ответы (2)


Если вы не хотите помечать записи, где 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 для ваших строк), последние 2 строки изменятся на:

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
person JBrooks    schedule 19.08.2015

Работает ли ниже для вашего сценария?

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)
)
person cqi    schedule 19.08.2015