Oracle 数据库中递归查询

方法一:使用 CONNECT BY(传统方式)

-- 假设表名为 my_table,字段为 id 和 parent_id

SELECT id

FROM my_table

START WITH id = '根节点ID' -- 从根节点开始

CONNECT BY PRIOR id = parent_id -- 递归条件:父节点的 id = 子节点的 parent_id

MINUS -- 去重(可选)

-- 或者使用 NOT EXISTS 来筛选叶子节点

SELECT id

FROM my_table t

WHERE NOT EXISTS (

SELECT 1

FROM my_table t2

WHERE t2.parent_id = t.id

)

START WITH id = '根节点ID'

CONNECT BY PRIOR id = parent_id;

方法二:使用 WITH 递归(推荐,更标准)

WITH RECURSIVE cte AS (

-- 基础查询:从根节点开始

SELECT id, parent_id, 1 as level

FROM my_table

WHERE id = '根节点ID' -- 替换为实际的根节点ID

UNION ALL

-- 递归查询:查找所有子节点

SELECT t.id, t.parent_id, c.level + 1

FROM my_table t

INNER JOIN cte c ON t.parent_id = c.id

)

-- 筛选叶子节点(没有子节点的节点)

SELECT c.id

FROM cte c

WHERE NOT EXISTS (

SELECT 1

FROM my_table t

WHERE t.parent_id = c.id

);

方法三:一步到位(最简洁)

WITH cte AS (

SELECT id, parent_id

FROM my_table

START WITH id = '根节点ID'

CONNECT BY PRIOR id = parent_id

)

SELECT id

FROM cte c

WHERE NOT EXISTS (

SELECT 1 FROM my_table WHERE parent_id = c.id

);

示例

假设数据如下:

id | parent_id

----|----------

A | NULL (根)

B | A

C | A

D | B

E | B

查询根节点 A 的所有叶子节点:

SELECT id

FROM my_table

START WITH id = 'A'

CONNECT BY PRIOR id = parent_id

MINUS

SELECT id

FROM my_table

WHERE parent_id IS NOT NULL;

结果:C, D, E

性能优化建议

  1. 创建索引:

CREATE INDEX idx_parent_id ON my_table(parent_id);

CREATE INDEX idx_id ON my_table(id);

  1. 如果数据量大,考虑使用 NO_CYCLE:

START WITH id = '根节点ID'

CONNECT BY NOCYCLE PRIOR id = parent_id

相关推荐
God__is__a__girl4 分钟前
Oracle驱动版本引发ORA-01461批量插入异常排查与解决
数据库·oracle
少年攻城狮15 分钟前
Oracle系列---【两个环境,表结构一致,数据量一致,索引也一致,为什么同样的sql执行时间却不一致?】
数据库·sql·oracle
l1t15 分钟前
解决用docker安装umbra数据库遇到的FATAL:Operation not permitted错误
数据库·docker·容器
2401_8942419223 分钟前
机器学习与人工智能
jvm·数据库·python
GentleDevin38 分钟前
Redis服务常用命令
数据库·oracle
難釋懷43 分钟前
Redis分片集群手动故障转移
数据库·redis·缓存
无名-CODING1 小时前
从零开始!Vue3+SpringBoot前后端分离项目Docker部署实战(上):环境搭建与数据库容器化
数据库·spring boot·docker
Bdygsl1 小时前
MySQL(2)—— CRUD
数据库·mysql
chushiyunen1 小时前
python edge-tts实现tts文本转语音、音频
数据库·python·音视频
原来是猿1 小时前
MySQL【事务中 - 事务的隔离级别】
数据库·mysql