Oracle HR 模式递归函数练习(基于 employees 表)

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;

总结

  1. 核心语法START WITH(根节点)+ CONNECT BY PRIOR(父子关系)
  2. 方向判断
    • 向下查下级:PRIOR 员工ID = 上级ID
    • 向上查上级:PRIOR 上级ID = 员工ID
  3. 实用函数LEVEL(层级)、SYS_CONNECT_BY_PATH(路径拼接)
  4. employees 表是学习 Oracle 递归的最佳案例,吃透这 5 个例子就能掌握 90% 递归场景
相关推荐
小陈工2 小时前
2026年3月31日技术资讯洞察:AI智能体安全、异步编程突破与Python运行时演进
开发语言·jvm·数据库·人工智能·python·安全·oracle
杨云龙UP2 小时前
Linux生产环境下Oracle RMAN 备份、核查、清理与验证常用命令整理_20260330
linux·运维·服务器·数据库·oracle
橙子家3 小时前
关于列式存储(Column-base Storage)的几个要点解读
数据库
٩( 'ω' )و2603 小时前
MySQL基础
数据库·mysql
生命不息战斗不止(王子晗)3 小时前
mysql基础语法面试题
java·数据库·mysql
知识分享小能手3 小时前
MongoDB入门学习教程,从入门到精通,MongoDB应用程序设计知识点梳理(9)
数据库·学习·mongodb
一直都在5724 小时前
Redis (一)
数据库·redis·缓存
字符串str4 小时前
sql的基本技术栈
数据库·sql·oracle
秦jh_4 小时前
【Redis】客户端使用
数据库·redis·缓存