Oracle 中递归查询 核心用 CONNECT BY 语法(专用于树形结构查询),employees 表是完美的练习素材:
- 字段:
employee_id(员工 ID)、first_name||last_name(员工姓名)、manager_id(上级 ID) - 关系:
manager_id关联employee_id,形成上下级树形层级(总裁→总监→经理→普通员工)
先确认表结构(HR 用户默认表):
-- 查看 employees 表核心字段
SELECT employee_id, last_name, manager_id, job_id
FROM employees;
下面给你5 个由浅入深的递归练习示例,直接复制运行即可。
练习 1:基础递归 - 查询所有员工的上下级层级(从总裁到基层)
需求:展示每个员工的层级、姓名、上级 ID,从最高级(总裁,manager_id 为 NULL)开始递归。
SELECT
-- LEVEL 是Oracle伪列,代表递归层级(根节点=1)
LEVEL AS 层级,
employee_id AS 员工ID,
last_name AS 员工姓名,
manager_id AS 上级ID
FROM employees
-- 递归条件:上级ID = 员工ID(父子关联)
CONNECT BY PRIOR employee_id = manager_id
-- 根节点:总裁(没有上级,manager_id IS NULL)
START WITH manager_id IS NULL
-- 排序:按层级、员工ID排序
ORDER SIBLINGS BY employee_id;
✅ 核心语法:
START WITH:指定递归根节点(起始行)CONNECT BY PRIOR:指定父子关联关系LEVEL:自动生成递归层级
练习 2:反向递归 - 从指定员工向上查所有上级(溯源)
需求:查询员工「Whalen」(employee_id=200)的所有上级,直到总裁。
SELECT
LEVEL AS 溯源层级,
employee_id,
last_name,
manager_id
FROM employees
-- 反向递归:PRIOR 放在 manager_id(子查父)
CONNECT BY PRIOR manager_id = employee_id
-- 起始节点:指定员工 Whalen
START WITH employee_id = 200;
✅ 关键点:递归方向
- 向下查下级:
PRIOR employee_id = manager_id - 向上查上级:
PRIOR manager_id = employee_id
练习 3:递归 + 函数 - 拼接员工的完整上级链
需求 :给每个员工生成完整上级路径 (如:King→Kochhar→Whalen),用 SYS_CONNECT_BY_PATH 递归拼接。
SELECT
employee_id AS 员工ID,
last_name AS 员工姓名,
-- 递归拼接路径,分隔符用 →
SYS_CONNECT_BY_PATH(last_name, '→') AS 完整上级链
FROM employees
CONNECT BY PRIOR employee_id = manager_id
START WITH manager_id IS NULL
ORDER SIBLINGS BY employee_id;
✅ 高阶函数:SYS_CONNECT_BY_PATH(列名, 分隔符) → 自动生成树形路径
练习 4:递归过滤 - 只查询指定层级的员工
需求 :查询第 2 层级(总裁的直接下属)所有员工。
SELECT
LEVEL AS 层级,
employee_id,
last_name,
job_id
FROM employees
WHERE LEVEL = 2 -- 过滤递归层级
CONNECT BY PRIOR employee_id = manager_id
START WITH manager_id IS NULL
ORDER BY employee_id;
✅ 技巧:WHERE LEVEL = 数字 精准筛选递归层级
练习 5:递归统计 - 每个上级的下属总人数
需求 :统计每个管理者直接 + 间接下属的总数量(递归计数)。
SELECT
e.employee_id AS 管理者ID,
e.last_name AS 管理者姓名,
-- 子查询递归统计下属总数
(SELECT COUNT(*) FROM employees
CONNECT BY PRIOR employee_id = manager_id
START WITH manager_id = e.employee_id) AS 下属总人数
FROM employees e
-- 只展示有下属的管理者
WHERE EXISTS (SELECT 1 FROM employees WHERE manager_id = e.employee_id)
ORDER BY 下属总人数 DESC;
✅ 进阶用法:递归查询嵌套在统计函数中,实现树形计数
练习 6:WITH 递归子句(11gR2+ 通用递归语法)
Oracle 11gR2 开始支持 ANSI 标准递归 WITH,兼容其他数据库(MySQL/PostgreSQL),推荐掌握:
-- 递归CTE查询员工层级
WITH emp_tree(员工ID, 姓名, 上级ID, 层级) AS (
-- 锚点成员(根节点:总裁)
SELECT employee_id, last_name, manager_id, 1
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- 递归成员(连接子节点)
SELECT e.employee_id, e.last_name, e.manager_id, et.层级 + 1
FROM employees e
JOIN emp_tree et ON e.manager_id = et.员工ID
)
SELECT * FROM emp_tree
ORDER BY 层级, 员工ID;
总结
- 核心语法 :
START WITH(根节点)+CONNECT BY PRIOR(父子关系) - 方向判断 :
- 向下查下级:
PRIOR 员工ID = 上级ID - 向上查上级:
PRIOR 上级ID = 员工ID
- 向下查下级:
- 实用函数 :
LEVEL(层级)、SYS_CONNECT_BY_PATH(路径拼接) - employees 表是学习 Oracle 递归的最佳案例,吃透这 5 个例子就能掌握 90% 递归场景