Oracle 11g查询符合条件的记录及其所有父级至根节点(无重复)
Oracle 11gR2 树形查询:获取匹配节点及所有唯一父节点路径
针对你这个树形结构表的需求——找出所有name='testX'的节点,以及它们向上到根节点的所有父节点,且父节点不重复——在Oracle 11.2.0.4里有两种简洁的实现方式:
方法一:使用CONNECT BY(传统树形查询)
这种写法最直接,利用Oracle原生的树形查询语法,代码简洁易读:
SELECT DISTINCT id, pid, name FROM your_table -- 替换成你的实际表名 START WITH name = 'testX' CONNECT BY PRIOR pid = id ORDER BY id;
逻辑拆解:
START WITH name = 'testX':指定查询的起始节点是所有名称为testX的记录(也就是示例里的ID1、4、11)。CONNECT BY PRIOR pid = id:递归向上遍历父节点——把当前节点的pid和父节点的id关联,直到遍历到根节点(pid为空的记录)。DISTINCT:因为不同的起始节点可能共享父节点(比如ID4和11的父节点都是3,3的父节点是2),用这个关键字去掉重复的父节点记录。ORDER BY id:只是为了和你给出的示例结果顺序一致,可根据需求调整。
方法二:使用递归CTE(WITH子句)
如果后续需要更复杂的逻辑扩展,递归CTE会更灵活,11gR2已经完全支持这种写法:
WITH recursive_paths AS ( -- 第一步:获取所有匹配的起始节点 SELECT id, pid, name FROM your_table WHERE name = 'testX' UNION ALL -- 第二步:递归向上查找父节点,直到根节点 SELECT t.id, t.pid, t.name FROM your_table t JOIN recursive_paths rp ON t.id = rp.pid ) -- 去重并排序 SELECT DISTINCT id, pid, name FROM recursive_paths ORDER BY id;
逻辑拆解:
- CTE的第一个分支先筛选出所有
name='testX'的节点。 - 第二个递归分支通过JOIN把每个已找到节点的父节点加入结果集,直到没有父节点可遍历。
- 最后同样用
DISTINCT去重共享的父节点,保证结果里没有重复记录。
两种方法都能得到你预期的结果:
| ID | PID | NAME |
|---|---|---|
| 1 | testX | |
| 2 | test2 | |
| 3 | 2 | test3 |
| 4 | 3 | testX |
| 5 | 3 | test5 |
| 11 | 5 | testX |
内容的提问来源于stack exchange,提问作者archjkee
相关产品推荐
相关产品推荐

