I have a requirement to build a table from a hierarchical table. Table structure as below:
emp_hier table:
emp_id | supervisorId |
---|---|
100 | null |
1 | 100 |
2 | 1 |
3 | 2 |
New table:
I have to write a select query on the emp_heir table and the selected data should look like this:
sel_emp_id | rel_emp_id | relation | depth_lvl |
---|---|---|---|
100 | 100 | self | 0 |
100 | 1 | My Repotee | -1 |
100 | 2 | My Repotee | -2 |
100 | 3 | My Repotee | -3 |
1 | 100 | My Mgr | 1 |
1 | 1 | self | 0 |
1 | 2 | My Repotee | -1 |
1 | 3 | My Repotee | -2 |
2 | 1 | My Mgr | 1 |
2 | 2 | self | 0 |
2 | 3 | My Repotee | -1 |
3 | 100 | My Mgr | 3 |
3 | 1 | My Mgr | 2 |
3 | 2 | My Mgr | 1 |
3 | 3 | self | 0 |
You can use UNION ALL
to combine a hierarchical query to get each row and its children to another hierarchical query to get all the ancestors:
SELECT CONNECT_BY_ROOT emp_id AS sel_emp_id,
emp_id AS rel_emp_id,
CASE LEVEL WHEN 1 THEN 'Self' ELSE 'My Reportee' END AS relation,
1 - LEVEL AS depth_lvl
FROM emp_hier
CONNECT BY PRIOR emp_id = supervisorid
UNION ALL
SELECT CONNECT_BY_ROOT emp_id,
emp_id,
'My Mgr',
LEVEL - 1
FROM emp_hier
WHERE LEVEL > 1
CONNECT BY PRIOR supervisorid = emp_id
ORDER BY sel_emp_id, depth_lvl DESC
Which, for your sample data:
CREATE TABLE emp_hier (emp_id, supervisorId) AS
SELECT 100, null FROM DUAL UNION ALL
SELECT 1, 100 FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 3, 2 FROM DUAL;
Outputs:
SEL_EMP_ID REL_EMP_ID RELATION DEPTH_LVL 1 100 My Mgr 1 1 1 Self 0 1 2 My Reportee -1 1 3 My Reportee -2 2 100 My Mgr 2 2 1 My Mgr 1 2 2 Self 0 2 3 My Reportee -1 3 100 My Mgr 3 3 1 My Mgr 2 3 2 My Mgr 1 3 3 Self 0 100 100 Self 0 100 1 My Reportee -1 100 2 My Reportee -2 100 3 My Reportee -3
db<>fiddle here