T-SQL-如何选择在一个项目中在一起工作时间最长的员工?

时间:2018-12-17 23:38:23

标签: sql sql-server database tsql

我有一个表,其示例名称为“雇员”,其中保存了每个雇员的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

3 个答案:

答案 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;

db<>fiddle

答案 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