SQL中的递归联接

时间:2019-04-08 07:57:15

标签: sql oracle

我的数据不足

当前数据

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; 

2 个答案:

答案 0 :(得分:1)

使用层次结构查询,并使用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          

db <>提琴here

答案 1 :(得分:0)

您可以使用以下查询:

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

因此,并非总是像上次那样总是在最后一栏中显示“ VP”。

如果经理名称应始终是顶级经理,则:

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