如何按日期检索重叠记录
How to retrieve overlap record by dates
我有这些表格
employee(id, name)
employeekey(id, employeeid, keyid, startdate, enddate)
key(id, code)
我在 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 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 在键分配日期上重叠我想查询 return。这是我的进步,但我得到了所有拥有 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
SELECT A.ID, 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;
给我们:请注意,两个 ID 都在这里表示,重叠的第 2+ 条记录也是如此
+----+----+----+------------+-------+------------+------------+
| | ID | id | employeeid | keyid | startdate | enddate |
+----+----+----+------------+-------+------------+------------+
| 1 | 1 | 2 | emp1 | k002 | 2016/06/02 | 2016/07/03 |
| 2 | 5 | 6 | emp3 | k005 | 2016/05/10 | 2016/05/15 |
+----+----+----+------------+-------+------------+------------+
我们可以通过这种方式取回重叠的记录。
--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
;
给我们:
+----+----+------------+-------+------------+------------+
| | id | employeeid | keyid | startdate | enddate |
+----+----+------------+-------+------------+------------+
| 1 | 1 | emp1 | k001 | 2016/01/01 | NULL |
| 2 | 2 | emp1 | k002 | 2016/06/02 | 2016/07/03 |
| 3 | 5 | emp3 | k004 | 2016/05/01 | 2016/05/15 |
| 4 | 6 | emp3 | k005 | 2016/05/10 | 2016/05/15 |
+----+----+------------+-------+------------+------------+
我会尝试EXISTS
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
);
我有这些表格
employee(id, name)
employeekey(id, employeeid, keyid, startdate, enddate)
key(id, code)
我在 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 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 在键分配日期上重叠我想查询 return。这是我的进步,但我得到了所有拥有 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
SELECT A.ID, 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;
给我们:请注意,两个 ID 都在这里表示,重叠的第 2+ 条记录也是如此
+----+----+----+------------+-------+------------+------------+
| | ID | id | employeeid | keyid | startdate | enddate |
+----+----+----+------------+-------+------------+------------+
| 1 | 1 | 2 | emp1 | k002 | 2016/06/02 | 2016/07/03 |
| 2 | 5 | 6 | emp3 | k005 | 2016/05/10 | 2016/05/15 |
+----+----+----+------------+-------+------------+------------+
我们可以通过这种方式取回重叠的记录。
--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
;
给我们:
+----+----+------------+-------+------------+------------+
| | id | employeeid | keyid | startdate | enddate |
+----+----+------------+-------+------------+------------+
| 1 | 1 | emp1 | k001 | 2016/01/01 | NULL |
| 2 | 2 | emp1 | k002 | 2016/06/02 | 2016/07/03 |
| 3 | 5 | emp3 | k004 | 2016/05/01 | 2016/05/15 |
| 4 | 6 | emp3 | k005 | 2016/05/10 | 2016/05/15 |
+----+----+------------+-------+------------+------------+
我会尝试EXISTS
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
);