我有一个包含销售部门列表的表,如下所示:
+-------+---------------+-----------+
|DEPT_ID|DEPT_NAME |DEPT_PARENT|
+-------+---------------+-----------+
|5500 |World | |
|5510 |Region 1 |5500 |
|5511 |Cell 1 Region 1|5510 |
|5512 |Cell 2 Region 1|5510 |
|5513 |Cell 3 Region 1|5510 |
|5514 |Cell 4 Region 1|5510 |
|5515 |Cell 5 Region 1|5510 |
|5520 |Region 2 |5500 |
|5521 |Cell 1 Region 2|5520 |
|5522 |Cell 2 Region 2|5520 |
|5530 |Region 3 |5500 |
|5531 |Cell 1 Region 3|5530 |
|5532 |Cell 2 Region 3|5530 |
|5540 |Region 4 |5500 |
|5533 |Cell 1 Region 4|5540 |
|5534 |Cell 2 Region 4|5533 |
|5590 |Region 5 |5500 |
|5591 |Cell 1 Region 5|5590 |
+-------+---------------+-----------+
我需要一个返回所有可能的子路径的查询。因此,对于前三行,应为:
5500 5510
5500 5511
5510 5511
因此,对于每个可能的子路径,它将返回路径的第一个和最后一个部门。通过执行此操作相当容易:
SELECT d.*, LTRIM (SYS_CONNECT_BY_PATH (dept_id, '-'), '-') AS PATH
FROM depts d
START WITH dept_parent IS NULL
CONNECT BY PRIOR dept_id = dept_parent
但是我如何获得所有可能的子路径?
我知道您要生成一个闭合表,其中包含层次结构中的所有可能路径。
这里是使用标准递归查询来实现的解决方案:
with cte(node_id, dept_id, dept_parent, lvl) as (
select dept_id node_id, dept_id, dept_parent, 0 lvl from dept
union all
select c.node_id, d.dept_id, d.dept_parent, c.lvl + 1
from cte c
inner join dept d on d.dept_id = c.dept_parent
)
select dept_id ancestor, node_id node, lvl
from cte
where lvl > 0
order by node, ancestor