Классическая таблица самосоединения, управляемая менеджером

Есть ли способ добраться до корня иерархии с помощью одного оператора SQL?

Значимые столбцы таблицы будут: EMP_ID, MANAGER_ID.

MANAGER_ID самостоятельно присоединяется к EMP_ID, поскольку менеджер также является сотрудником. Учитывая EMP_ID, есть ли способ добраться до сотрудника (менеджера) (поднимаясь по цепочке), где EMP_ID равен нулю?

Другими словами, лучший парень в организации?

Я использую SQL Server 2008

Спасибо.


person kmansoor    schedule 15.11.2013    source источник
comment
Я предполагаю, что у вас здесь несбалансированное дерево. Мое предложение - реализовать диспетчер функций (emp_id), который будет полностью подниматься по цепочке. таким образом вы могли select emp_id, manager(emp_id) from yourtable.   -  person Brett Schneider    schedule 15.11.2013
comment
Возможно, вы захотите прочитать этот вопрос и ответ SO: stackoverflow.com/questions/1757260/   -  person Igor Korkhov    schedule 15.11.2013


Ответы (3)


Вам нужно общее табличное выражение. Помимо прочего, они могут выполнять рекурсивные запросы точно так же, как вы ищете.

person thyme    schedule 15.11.2013

Трудно найти единственный SQL-запрос, который принесет результат с текущей структурой вашей таблицы. Как сказал Бретт, вы можете попробовать с сохраненной функцией.

Но я считаю, что лучше всего стоит обратить внимание на вложенные наборы, что является одним из хорошо подтвержденных дизайнов для деревья реализованы в реляционных базах данных.

person Andrei Nicusan    schedule 15.11.2013
comment
Трудно найти хоть один SQL-запрос, который принесет результат с текущей структурой. Нет это не так. См. Этот вопрос SO (и ответ), например: stackoverflow.com/questions/1757260/ - person Igor Korkhov; 15.11.2013

Это старый вопрос, но мне недавно пришлось сделать то же самое, поэтому я хочу привести пример выражения CTE для этого вопроса:

Предполагая, что у вас есть таблица:

EMP_ID MANAGER_ID  
1 NULL  
2 1  
3 NULL  
4 2  
5 3  
6 5  
7 3  

Выражение CTE начинается с поиска корневых уровней, у которых MANAGER_ID заполнен нулями, и завершения его с остальными сотрудниками простым внутренним соединением с корневым уровнем.

WITH PARENT
AS (
SELECT EMP_ID,
      MANAGER_ID,
      EMP_ID as BOSS
FROM tab
WHERE MANAGER_ID IS NULL
UNION ALL
SELECT T.EMP_ID,
       T.MANAGER_ID,
       PARENT.BOSS
FROM PARENT
    INNER JOIN TAB T ON T.MANAGER_ID = PARENT.EMP_ID)
SELECT *
FROM parent;

Это дает в результате:

EMP_ID MANAGER_ID BOSS
1 NULL 1
3 NULL 3
5 3 3
7 3 3
6 5 3
2 1 1
4 2 1
person Paco    schedule 03.05.2018