T-SQL - Как я могу выбрать сотрудников, которые дольше всего работали вместе над одним проектом? - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть таблица с именем примера «Сотрудники», в которой я сохраняю идентификатор каждого сотрудника, идентификатор проекта, над которым они работают или работали, а также дату, когда каждый сотрудник начал работать над проектом, и дату, когда они закончили.работая над этим.

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

Мне нужно написать запрос на выборку, чтобы найти пару сотрудников, которые больше всего работали вместе над Проектом.Не могли бы вы объяснить, как это должно произойти?Самым сложным для меня является то, как определить, работали ли два сотрудника одновременно над одним проектом - вот почему я не опубликовал «форму попытки», потому что все мои попытки сводятся к самому внутреннему объединению, например * 1004.*

SELECT 
    A.EmployeeID, A.ProjectID, A.DateFrom, B.DateTo 
FROM 
    Employees A
INNER JOIN 
    Employees B on A.ProjectID = B.ProjectID

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Предполагая, что сотрудники работают над проектом только один период времени, вы можете выполнить самостоятельное объединение и агрегирование:

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;
0 голосов
/ 21 декабря 2018

!!!!!!!!!!! Пожалуйста, попробуйте это !!!!!!!

    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 
0 голосов
/ 18 декабря 2018

Сначала присоединитесь к столу вместе с собой на общих 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...