SQL Server - самостоятельное соединение - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть следующая таблица

EmployeeID  Name    ManagerID   
2           David   3
3           Roger   NULL
4           Marry   2
5           Joseph  2
7           Ben     2

Здесь Роджер - топ-менеджер Майк и Дэвид - менеджеры А остальные все сотрудники

Я ищу вывод, как это:

EmployeeName    ManagerName     TopManager
Marry           David           Roger
Joseph          David           Roger
Ben             David           Roger
NULL            David           Roger

Я пытался использовать Self Join как:

SELECT e1.Name EmployeeName, ISNULL(e2.name, 'Top Manager') AS ManagerName
FROM Employee e1
LEFT JOIN Employee e2
ON e1.ManagerID = e2.EmployeeID

но он не дает вывод, который я ищу.

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Я думаю, вам нужно сделать само присоединение дважды, чтобы получить желаемый результат.

Я создал запрос таким образом и получил вывод, который вы упомянули. Обратите внимание, что я не включил последнюю строку, которая имеет нулевое значение, и остальное так же, как это.

Запрос:

create table Employees (EmployeeID int, Name varchar(10), ManagerID int) 

Insert into Employees values 
(2, 'David'  , 3   )
,(3, 'Roger'  , NULL)
,(4, 'Marry'  , 2    )
,(5, 'Joseph' , 2    )
,(7, 'Ben'    , 2    )

select e.name as EmployeeName,  e1.name ManagerName,    e2.Name TopManager  
from Employees e 
left join Employees e1 on e.ManagerID = e1.employeeid 
left join Employees e2 on  e1.ManagerID = e2.EmployeeID 
where e.ManagerID is not null  and e1.ManagerID is not null 

Где задано условие для ограничения имен менеджера в столбце Сотрудник.

Выход:

EmployeeName    ManagerName  TopManager
Marry           David        Roger
Joseph          David        Roger
Ben             David        Roger
0 голосов
/ 01 ноября 2018

Если у вас могут быть разные топ-менеджеры, тогда нужен рекурсивный CTE:

with cte as (
      select employeeid, name, name as topmanager
      from Employee
      where managerid is null
      union all
      select t.employeeid, t.name, cte.topmanager
      from Employee t join
           cte
           on t.managerid = cte.employeeid
    )
select *
from cte;

Если есть только один топ-менеджер, то:

select e.*, topm.name as topmanager
from employee e cross join
     (select e2.* from employee e2 where e2.managerid is null) as topm
...