我正在尝试编写一个查询来获取所有节点及其祖先。数据库存储树(节点及其子/父)。我知道connect by可以给所有祖先,当与start with子句结合使用时,你可以获得单个节点的所有祖先。
这是一个快速举例说明我的目的。
节点边缘表:
+---------+-----------+
|child_id |parent_id |
+---------+-----------+
|2 |1 |
|3 |2 |
|4 |2 |
|5 |4 |
+---------+-----------+
我写的查询是:
select parent_id, child_id
from edges
start with child_id = 5
connect by child_id = prior parent_id
给出:
+---------+-----------+
|child_id |parent_id |
+---------+-----------+
|2 |1 |
|4 |2 |
|5 |4 |
+---------+-----------+
我正在寻找的是这样的:
+---------+-----------+
|child_id |parent_id |
+---------+-----------+
|2 |1 |
|3 |2 |
|3 |1 |
|4 |2 |
|4 |1 |
|5 |4 |
|5 |2 |
|5 |1 |
+---------+-----------+
因此每个节点都有一个记录,每个节点的祖先一直到根。我在构建查询以获得此结果时遇到了一些麻烦。有什么建议吗?
谢谢, mcangus
答案 0 :(得分:1)
使用CONNECT_BY_ROOT
运算符:
WITH edges (child_id, parent_id) AS (
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 3, 2 FROM DUAL UNION ALL
SELECT 4, 2 FROM DUAL UNION ALL
SELECT 5, 4 FROM DUAL
)
SELECT
child_id, CONNECT_BY_ROOT parent_id parent_id
FROM
edges
CONNECT BY
PRIOR child_id = parent_id
ORDER BY
child_id, parent_id DESC;
答案 1 :(得分:0)
以下查询解决了您的问题:
with tree (childid, parentid)
as
(select child_id, parent_id from
edges
union all
select t.childid, g.parent_id
from tree t
join edges g
on t.parentid = g.child_id)
select * from tree
order by childid, parentid desc
答案 2 :(得分:0)
我不认为“开始”会做你打算做的事情。这将限制您的根行,这就是您获得有限结果集的原因。您还希望CONNECT_BY_ROOT不仅可以获取child_id,还可以获取根行的child_id。免责声明:我不是一个神谕大师,我只是有一段时间。
SYS_CONNECT_BY_PATH只是额外信息。
select CONNECT_BY_ROOT child_id "CHILD_ID", parent_id, SYS_CONNECT_BY_PATH(child_id, '/') "PATH"
from edges
connect by child_id = prior parent_id;
结果:
CHILD_ID PARENT_ID PATH
2 1 /2
3 2 /3
3 1 /3/2
4 2 /4
4 1 /4/2
5 4 /5
5 2 /5/4
5 1 /5/4/2
查看docs。