Sql 如何按日期检索重叠记录
我有这些桌子 雇员ID,姓名 employeekeyid,employeeid,keyid,开始日期,结束日期 密钥ID,代码 我在employeekey中有日期重叠的记录Sql 如何按日期检索重叠记录,sql,date,sql-server-2008-r2,Sql,Date,Sql Server 2008 R2,我有这些桌子 雇员ID,姓名 employeekeyid,employeeid,keyid,开始日期,结束日期 密钥ID,代码 我在employeekey中有日期重叠的记录 id employeeid keyid startdate enddate 1 emp1 k001 01/01/2016 NULL 2 emp1 k002 02/06/2016 03/07/2016 3 emp2 k003
id employeeid keyid startdate enddate
1 emp1 k001 01/01/2016 NULL
2 emp1 k002 02/06/2016 03/07/2016
3 emp2 k003 01/06/2016 30/06/2016
4 emp2 k003 01/07/2016 15/07/2016
5 emp3 k004 01/05/2016 15/05/2016
6 emp3 k005 10/05/2016 15/05/2016
emp1和emp3在键分配的日期上重叠,我希望查询返回该值。这是我的进步,但我得到了所有拥有2个或更多密钥的员工,即使他们在日期上没有如上面结果所示的重叠。我只想要如下所示的重叠部分
id employeeid keyid startdate enddate
1 emp1 k001 01/01/2016 NULL
2 emp1 k002 02/06/2016 03/07/2016
5 emp3 k004 01/05/2016 15/05/2016
6 emp3 k005 10/05/2016 15/05/2016
进展
select e.id as employeeid, e.name, k.id as keyid, ek.startdate, ek.enddate
from employee e
inner join employeekey ek on ek.employeeid = e.id
inner join key k on k.id = ek.keyid
where exists
(
select count(1), e2.id, e2.name
from employee e2
inner join employeekey2 ek2 on ek2.employeeid = e2.id
where e.id = e2.id
group by e2.id, e2.name
having count(e2.id) > 1
)
order by 1
我们可以用这种方法把两个重叠的记录都找回来
--Optional to just use A.ID and B.* to see all the IDs
--Select a.ID, B.*
SELECT B.*
FROM employeeKey A
LEFT JOIN employeeKey B
on A.EmployeeID = B.EmployeeID
and (B.StartDate between A.StartDate and Coalesce(A.EndDate,GetDate()) OR
B.EndDate between A.StartDate and Coalesce(A.EndDate,GetDate()))
and A.KeyID < B.KeyID
Where B.ID is not null
--You could exclude the union and add the optional select.
UNION ALL
SELECT A.*
FROM employeeKey A
LEFT JOIN employeeKey B
on A.EmployeeID = B.EmployeeID
and (B.StartDate between A.StartDate and Coalesce(A.EndDate,GetDate()) OR
B.EndDate between A.StartDate and Coalesce(A.EndDate,GetDate()))
and A.KeyID < B.KeyID
Where B.ID is not null
Order by EmployeeID, KeyID
;
我们可以用这种方法把两个重叠的记录都找回来
--Optional to just use A.ID and B.* to see all the IDs
--Select a.ID, B.*
SELECT B.*
FROM employeeKey A
LEFT JOIN employeeKey B
on A.EmployeeID = B.EmployeeID
and (B.StartDate between A.StartDate and Coalesce(A.EndDate,GetDate()) OR
B.EndDate between A.StartDate and Coalesce(A.EndDate,GetDate()))
and A.KeyID < B.KeyID
Where B.ID is not null
--You could exclude the union and add the optional select.
UNION ALL
SELECT A.*
FROM employeeKey A
LEFT JOIN employeeKey B
on A.EmployeeID = B.EmployeeID
and (B.StartDate between A.StartDate and Coalesce(A.EndDate,GetDate()) OR
B.EndDate between A.StartDate and Coalesce(A.EndDate,GetDate()))
and A.KeyID < B.KeyID
Where B.ID is not null
Order by EmployeeID, KeyID
;
我会试试看
我会试试看
我认为您可以使用如下查询:
;with overlaps as (
select *
from employeekey ek
where exists (
select 1
from employeekey eki
where ek.id <> eki.id
and ek.employeeid = eki.employeeid
-- I use `<=` and `>=` instead of `between` because of date comparing problems with it
and ek.startdate >= eki.startdate
and ek.startdate <= coalesce(eki.enddate, getdate())
)
)
select *
from employeekey ek
where ek.employeeid in (
select employeeid
from overlaps
);
我认为您可以使用如下查询:
;with overlaps as (
select *
from employeekey ek
where exists (
select 1
from employeekey eki
where ek.id <> eki.id
and ek.employeeid = eki.employeeid
-- I use `<=` and `>=` instead of `between` because of date comparing problems with it
and ek.startdate >= eki.startdate
and ek.startdate <= coalesce(eki.enddate, getdate())
)
)
select *
from employeekey ek
where ek.employeeid in (
select employeeid
from overlaps
);
注意:完全正确。返回所有6条记录。注意:完全正确。返回所有6条记录。谢谢你的回答。我想要问题的第二个结果集输出。我现在得到的是第一个结果集。所以你得到了那些重叠emp1和emp3的密钥,但我想列出所有分配的密钥。在这种情况下,如果我们返回所有的a.*和b.*我看不到k001、k0041和4。您会注意到,在第一种方法中,两个记录的ID都存在。或者我们可以在我的更新中合并这两个结果。太棒了,谢谢@MaximusDecimus可能想看看shA.t的反应。清洁器似乎也能用。谢谢你的回答。我想要问题的第二个结果集输出。我现在得到的是第一个结果集。所以你得到了那些重叠emp1和emp3的密钥,但我想列出所有分配的密钥。在这种情况下,如果我们返回所有的a.*和b.*我看不到k001、k0041和4。您会注意到,在第一种方法中,两个记录的ID都存在。或者我们可以在我的更新中合并这两个结果。太棒了,谢谢@MaximusDecimus可能想看看shA.t的反应。清洁工似乎也能工作。
select id, employeeid, keyid, startdate, enddate
from employeekey ek1
where exists
(
select 1
from employeekey ek2
where ek1.id != ek2.id and
ek1.employeeid = ek2.employeeid and
ek2.startdate < Coalesce(ek1.enddate,GetDate()) and
Coalesce(ek2.EndDate,GetDate()) > ek1.startdate
)
;with overlaps as (
select *
from employeekey ek
where exists (
select 1
from employeekey eki
where ek.id <> eki.id
and ek.employeeid = eki.employeeid
-- I use `<=` and `>=` instead of `between` because of date comparing problems with it
and ek.startdate >= eki.startdate
and ek.startdate <= coalesce(eki.enddate, getdate())
)
)
select *
from employeekey ek
where ek.employeeid in (
select employeeid
from overlaps
);