递归查询是SQL中处理层次结构数据的关键技术,本文详细介绍通过递归CTE实现多级数据遍历的具体方法。
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
manager_id INT -- 指向上级,CEO的manager_id为NULL(或0,通常用NULL表示无上级)
);
INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (101, '马总', NULL); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (201, '张工', 101); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (202, '王工', 101); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (301, '李工', 201); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (401, '赵工', 301); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (402, '刘工', 301);
需要获取id=101人员及其所有下级关系,同时标注每个成员的层级,起始层级设为0。
使用递归CTE可以高效查询多级下属关系,以下SQL语句实现了层级标记功能:
WITH RECURSIVE subordinates AS (
-- 初始查询:定位基准员工
SELECT
id,
name,
manager_id,
0 AS level
FROM employees
WHERE id = 101
UNION ALL
-- 递归查询:逐级查找下属
SELECT
e.id,
e.name,
e.manager_id,
s.level + 1
FROM employees e
INNER JOIN subordinates s ON e.manager_id = s.id
)
SELECT *
FROM subordinates
ORDER BY level, id;

WITH RECURSIVE subordinates AS (...)是定义递归CTE的标准语法,其核心原理如下:
递归CTE包含两个关键部分:
SELECT id, name, manager_id, 1 AS level FROM employees WHERE id = 101
SELECT e.id, e.name, e.manager_id, s.level + 1 FROM employees e INNER JOIN subordinates s ON e.manager_id = s.id
最终查询直接引用CTE名称获取完整结果集。
假设数据结构如下:
执行过程分四个阶段:
递归CTE提供了一种高效处理层次数据的标准方法,相比传统方案具有更好的可读性和性能表现。