У меня есть данные ниже
Текущие данные
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;
мне кажется классика connect by prior
/ connect_by_root
: docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm и docs.oracle.com/cd/B19306_01/server.102/b14200/…
Вы можете использовать этот запрос:
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, см. дополнение к моему ответу.
Используйте иерархический запрос и 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
дб <> рабочий пример здесь
Вы уверены в выводе имени менеджера? ИЛИ вы хотите показать EmpName как ManagerName в соответствии с идентификатором менеджера