我有一个表,其示例名称为“雇员”,其中保存了每个雇员的ID,他们正在从事或已经从事的项目ID,每个雇员开始从事该项目的日期以及他们完成的日期。正在努力。
EmployeeID - ProjectID - DateStart - DateEnd
-------------------------------------------------------------
1 - 100 - 22/11/2017 - 14/12/2017
2 - 101 - 02/01/2017 - 19/10/2017
3 - 102 - 05/08/2017 - 09/07/2017
4 - 102 - 04/03/2017 - 12/03/2017
5 - 100 - 06/01/2017 - 22/12/2017
6 - 100 - 16/01/2017 - 22/12/2017
7 - 100 - 26/01/2017 - 22/07/2018
7 - 102 - 12/01/2017 - 22/12/2017
3 - 100 - 04/01/2017 - 20/11/2018
5 - 102 - 03/01/2017 - 22/10/2018
我需要编写一个选择查询来查找在一个项目上在一起工作时间最长的一对员工。您能解释一下该如何发生吗?对我而言,最困难的事情是如何检测两名员工是否同时在一个项目上工作-这就是为什么我没有发布任何“尝试形式”的原因,因为我的所有尝试都是通过自我内在的加入,例如>
SELECT
A.EmployeeID, A.ProjectID, A.DateFrom, B.DateTo
FROM
Employees A
INNER JOIN
Employees B on A.ProjectID = B.ProjectID
答案 0 :(得分:2)
首先将表与自己连接到常见的projectid
上,并且其中一个employeeid
大于另一个。这样可以使您获得有趣的员工对以及他们俩一直在从事的项目。然后,选择两个datestart
中较大的一个,两个dateend
中较小的一个。筛选那些开始少于结束的内容。使用datediff()
获取这两个日期之间的持续时间(以天为单位)。将rank()
与ORDER BY
一起使用,将日期之间的持续时间降低。这样,具有最长持续时间的记录将获得分配的1
等级。现在,从该集合中选择秩等于1
的所有记录。
SELECT x.employeeid1,
x.employeeid2,
x.projectid,
x.datestart,
x.dateend,
x.days
FROM (SELECT t1.employeeid employeeid1,
t2.employeeid employeeid2,
t1.projectid,
CASE
WHEN t1.datestart > t2.datestart THEN
t1.datestart
ELSE
t2.datestart
END datestart,
CASE
WHEN t1.dateend < t2.dateend THEN
t1.dateend
ELSE
t2.dateend
END dateend,
datediff(day,
CASE
WHEN t1.datestart > t2.datestart THEN
t1.datestart
ELSE
t2.datestart
END,
CASE
WHEN t1.dateend < t2.dateend THEN
t1.dateend
ELSE
t2.dateend
END) days,
rank() OVER (ORDER BY datediff(day,
CASE
WHEN t1.datestart > t2.datestart THEN
t1.datestart
ELSE
t2.datestart
END,
CASE
WHEN t1.dateend < t2.dateend THEN
t1.dateend
ELSE
t2.dateend
END) DESC) r
FROM elbat t1
INNER JOIN elbat t2
ON t2.projectid = t1.projectid
AND t2.employeeid > t1.employeeid
WHERE CASE
WHEN t1.datestart > t2.datestart THEN
t1.datestart
ELSE
t2.datestart
END
<
CASE
WHEN t1.dateend < t2.dateend THEN
t1.dateend
ELSE
t2.dateend
END) x
WHERE x.r = 1;
答案 1 :(得分:1)
假设员工仅在一个项目上工作一段时间,则可以进行自我加入和汇总:
select top (1) e1.projectId, e1.employeeId, e2.employeeId
from employees e1 join
employees e2
on e1.projectId = e2.projectId and
e1.employeeId < e2.employeeId
group by e1.employeeId, e2.employeeId
order by datediff(day,
(case when e1.datestart > e2.datestart then e1.datestart else e2.datestart end),
(case when e2.dateend < e1.dateend then e2.dateend else e1.dateend end)
) desc;
答案 2 :(得分:0)
!!!!!!!!!!!请尝试一下!!!!!!!
select 1 as EmployeeID,100 as ProjectID,cast (convert(datetime, '11-22-
2017',101) as date) as DateStart,cast (convert(datetime, '12-14-2017',101) as
date) as DateEnd into #Test
insert into #Test values
(2,101,'01/02/2017','10/19/2017'),
(3,102,'08/05/2017','07/09/2017'),
(4,102,'03/04/2017','03/12/2017'),
(5,100,'01/06/2017','12/22/2017'),
(6,100,'01/16/2017','12/22/2017'),
(7,100,'01/26/2017','07/22/2018'),
(7,102,'01/12/2017','12/22/2017'),
(3,100,'01/04/2017','11/20/2018'),
(5,102,'01/03/2017','10/22/2018')
select distinct * , DATEDIFF(dd, srt_date ,End_date ) as
Max_No_Days_Worked_Togather
from (
select
t1.EmployeeID as t1_EmployeeID, t1.ProjectID as t1_ProjectID , t1.DateStart
as t1_DateStart ,
t1.DateEnd as t1_DateEnd, t.EmployeeID as t_EmployeeID, t.ProjectID as
t_ProjectID ,t.DateStart as t_DateStart,
t.DateEnd as t_DateEnd,
case
when t1.DateStart > t.DateStart then t1.DateStart
when t1.DateStart < t.DateStart then t.DateStart end as srt_date,
case
when t1.DateEnd > t.DateEnd then t.DateEnd
when t1.DateEnd < t.DateEnd then t1.DateEnd end as End_date
from #Test t1
left join #Test t on t1.ProjectID=t.ProjectID and t1.EmployeeID<>t.EmployeeID
)s
order by DATEDIFF(dd, srt_date ,End_date ) desc