WITH RECURSIVE org_tree AS(-- 非递归部分(根节点)SELECT
id,
name,
manager_id,
position,1ASlevel,
CAST(name ASCHAR(255))AS path
FROM employees
WHERE manager_id ISNULL-- 根节点,即 CEO UNIONALL-- 递归部分SELECT
e.id,
e.name,
e.manager_id,
e.position,
t.level+1ASlevel,
CONCAT(t.path,' -> ', e.name)AS path
FROM employees e
JOIN org_tree t
ON e.manager_id = t.id
)SELECT*FROM org_tree
ORDERBYlevel, manager_id;
4. 查询结果
id
name
manager_id
position
level
path
1
Alice
NULL
CEO
1
Alice
2
Bob
1
CTO
2
Alice -> Bob
3
Carol
1
CFO
2
Alice -> Carol
4
David
2
Engineer
3
Alice -> Bob -> David
5
Eve
2
Engineer
3
Alice -> Bob -> Eve
6
Frank
3
Accountant
3
Alice -> Carol -> Frank
7
Grace
4
Intern
4
Alice -> Bob -> David -> Grace
三、逐步剖析递归 SQL 执行过程
第 1 步:非递归部分执行,查找根节点(Alice,CEO)。
第 2 步:递归查找下属,即 manager_id 为 Alice 的员工(Bob 和 Carol)。
第 3 步:继续递归,查找 Bob 和 Carol 的下属(David、Eve、Frank)。
第 4 步:直到没有下属,递归结束。
四、案例 2:分类目录的层级查询
1. 数据表结构categories
id
category_name
parent_id
1
Electronics
NULL
2
Mobile Phones
1
3
Laptops
1
4
iPhone
2
5
Samsung
2
6
Dell
3
7
MacBook
3
2. 查询分类目录树(层级展示)
WITH RECURSIVE category_tree AS(SELECT
id,
category_name,
parent_id,1ASlevel,
CAST(category_name ASCHAR(255))AS path
FROM categories
WHERE parent_id ISNULL-- 顶级分类 UNIONALLSELECT
c.id,
c.category_name,
c.parent_id,
t.level+1ASlevel,
CONCAT(t.path,' -> ', c.category_name)AS path
FROM categories c
JOIN category_tree t
ON c.parent_id = t.id
)SELECT*FROM category_tree
ORDERBYlevel, parent_id;
3. 查询结果
id
category_name
parent_id
level
path
1
Electronics
NULL
1
Electronics
2
Mobile Phones
1
2
Electronics -> Mobile Phones
3
Laptops
1
2
Electronics -> Laptops
4
iPhone
2
3
Electronics -> Mobile Phones -> iPhone
5
Samsung
2
3
Electronics -> Mobile Phones -> Samsung
6
Dell
3
3
Electronics -> Laptops -> Dell
7
MacBook
3
3
Electronics -> Laptops -> MacBook
五、应用场景与优化建议
1. 应用场景
组织架构树:查询上下级关系。
分类目录:电商商品分类,处理嵌套分类树。
评论系统:层级评论回复,构建嵌套评论。
权限管理:递归遍历角色与权限关系。
2. 优化建议
限制递归深度:防止死循环或层级过深导致查询缓慢。
WITH RECURSIVE category_tree AS(SELECT id, category_name, parent_id,1ASlevelFROM categories WHERE parent_id ISNULLUNIONALLSELECT c.id, c.category_name, c.parent_id, t.level+1FROM categories c
JOIN category_tree t ON c.parent_id = t.id
WHERE t.level<5-- 限制递归深度为 5)SELECT*FROM category_tree;