Рекурсивное соединение в SQL

У меня есть данные ниже

Текущие данные

Emp id  Emp Name    Manger ID
100     Employee    101
101     Team Lead   102
102     Manager     103
103     Sr. Manager 104
104     Director    105
105     VP          0

Ожидаемые данные:

Emp id  Emp Name    Manger ID   Manager Name
105     VP          0           Null
104     Director    105         VP
103     Sr. Manager 104         VP
102     Manager     103         VP
101     Team Lead   102         VP
100     Employee    101         VP

Как мы можем этого добиться??

select c.*
  from (select a.emp_id
              ,a.emp_name
              ,a.manager_id as manager_id
              ,b.emp_name   as manager_name
          from (select emp_id
                      ,emp_name
                      ,manager_id
                  from emp_test
                 WHERE manager_id <> 0) a
              , --parent is present                                   
               (select emp_id
                      ,emp_name
                      ,manager_id
                  from emp_test) b --all records                                  
         where a.manager_id = b.emp_id
        union all
        select emp_id
              ,emp_name
              ,manager_id as manager_id
              ,'' as manager_name
          from emp_test
         WHERE manager_id = 0) c
 ORDER BY 1 desc
         ,2 asc; 

Вы уверены в выводе имени менеджера? ИЛИ вы хотите показать EmpName как ManagerName в соответствии с идентификатором менеджера

Nitika 08.04.2019 10:07

мне кажется классика connect by prior / connect_by_root: docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.ht‌​m и docs.oracle.com/cd/B19306_01/server.102/b14200/…

Caius Jard 08.04.2019 10:08
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
85
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать этот запрос:

select emp_id, emp_name, manager_id, prior emp_name as manager_name
from emp_test
start with manager_id = 0
connect by prior emp_id = manager_id;

Обратите внимание, что это выведет:

EMP_ID  EMP_NAME    MANAGER_ID MANAGER_NAME
105     VP          0   
104     Director    105        VP
103     Sr. Manager 104        Director
102     Manager     103        Sr. Manager
101     Team Lead   102        Manager
100     Employee    101        Team Lead

Так что не всегда "ВП" в последней колонке, как у вас.

Если имя менеджера всегда должно быть менеджером верхнего уровня, то:

select emp_id, emp_name, manager_id,
       case when manager_id <> 0 then connect_by_root emp_name end as manager_name
from emp_test
start with manager_id = 0
connect by prior emp_id = manager_id;

Выход:

EMP_ID  EMP_NAME    MANAGER_ID MANAGER_NAME
105     VP          0   
104     Director    105        VP
103     Sr. Manager 104        VP
102     Manager     103        VP
101     Team Lead   102        VP
100     Employee    101        VP

ваше утверждение не дает правильного результата. в примере manager_name должно быть VP

hotfix 08.04.2019 10:21

@hotfix, см. дополнение к моему ответу.

trincot 08.04.2019 10:26
Ответ принят как подходящий

Используйте иерархический запрос и CONNECT_BY_ROOT, чтобы получить имя менеджера в корне иерархии:

Настройка Oracle:

CREATE TABLE table_name ( Emp_id, Emp_Name, Manager_ID ) AS
SELECT 100,   'Employee',    101 FROM DUAL UNION ALL
SELECT 101,   'Team Lead',   102 FROM DUAL UNION ALL
SELECT 102,   'Manager',     103 FROM DUAL UNION ALL
SELECT 103,   'Sr. Manager', 104 FROM DUAL UNION ALL
SELECT 104,   'Director',    105 FROM DUAL UNION ALL
SELECT 105,   'VP',          0 FROM DUAL;

Запрос:

SELECT t.*,
       CASE WHEN Manager_id <> 0 THEN CONNECT_BY_ROOT( Emp_Name ) END AS Manager_Name
FROM   table_name t
START WITH Manager_Id = 0
CONNECT BY PRIOR Emp_id = Manager_ID

Выход:

EMP_ID | EMP_NAME    | MANAGER_ID | MANAGER_NAME
-----: | :---------- | ---------: | :-----------
   105 | VP          |          0 | null        
   104 | Director    |        105 | VP          
   103 | Sr. Manager |        104 | VP          
   102 | Manager     |        103 | VP          
   101 | Team Lead   |        102 | VP          
   100 | Employee    |        101 | VP          

дб <> рабочий пример здесь

Другие вопросы по теме