You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Connect by Prior同时查询实体的父节点与子节点?

解决方法:同时获取指定节点的父节点与子节点

要同时拿到id=2的所有父节点(含祖先)和子节点(含子孙),你可以通过两种方式实现,基于Oracle的CONNECT BY语法:

方法1:合并两个单向遍历查询

原语句是从id=2向下遍历所有子节点(包括自身),如果要获取父节点,我们需要反过来向上遍历所有祖先节点,然后用UNION合并两个结果(自动去重,避免重复出现id=2的记录):

-- 向下查询:获取id=2的所有子节点(含自身)
SELECT * 
FROM myTable tab 
CONNECT BY PRIOR tab.id = tab.child_id 
START WITH tab.id = 2

UNION

-- 向上查询:获取id=2的所有父节点(含自身)
SELECT * 
FROM myTable tab 
CONNECT BY tab.id = PRIOR tab.child_id 
START WITH tab.id = 2;

原理说明

  • 第一个CONNECT BY PRIOR tab.id = tab.child_id:表示"当前节点的id等于下一个节点的child_id",也就是从start节点往下找所有子节点。
  • 第二个CONNECT BY tab.id = PRIOR tab.child_id:表示"当前节点的id等于上一个节点的child_id",也就是从start节点往上找所有父节点/祖先。
  • UNION会自动合并两个结果集,并去掉重复的记录(因为start节点会在两个查询中都出现)。

方法2:使用双向遍历+NOCYCLE关键字

如果你想用单条查询实现,可以通过OR把双向遍历的条件合并,同时加上NOCYCLE防止出现循环引用导致的无限遍历(比如表中存在A→B→A的循环关系时):

SELECT * 
FROM myTable tab 
CONNECT BY NOCYCLE (tab.id = PRIOR tab.child_id OR PRIOR tab.id = tab.child_id)
START WITH tab.id = 2;

注意事项

  • 这种方式会一次性返回所有相关节点,但如果你的树形结构存在循环引用,必须加上NOCYCLE,否则查询会报错。
  • 你可以额外添加LEVEL列来区分节点的层级关系,比如SELECT *, LEVEL FROM ...,方便判断是父节点还是子节点。

内容的提问来源于stack exchange,提问作者Ananta

火山引擎 最新活动