Oracle connect by 查找子、祖先对

Oracle connect by to find child, ancestor pairs

我正在尝试编写查询以获取所有节点及其祖先。数据库存储一棵树(节点及其 children/parents)。我知道 connect by 可以给出所有的祖先,当加上 start with 子句时,你可以获得单个节点的所有祖先。

这里有一个简单的例子来说明我要做什么。

节点边table:

+---------+-----------+
|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          |
+---------+-----------+

所以每个节点都有一条记录,记录了它的每个祖先,一直到根。我在构建查询以获得此结果时遇到了一些麻烦。有什么建议吗?

谢谢, 麦坎格斯

以下查询解决了您的问题:

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

使用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;

我认为 "start with" 没有达到您的预期。这将限制您的根行,这就是您获得有限结果集的原因。您还希望 CONNECT_BY_ROOT 不仅获得根行的 child_id,而且获得 child_id。免责声明:我不是 oracle 大师,我只是有一些时间。

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