Oracle LEVEL 函数练习(HR 模式 employees 表)

Oracle LEVEL 函数练习(HR 模式 employees 表)

LEVEL 是 Oracle 伪列 ,专门用于生成层级数据 / 递归查询 ,配合 CONNECT BY 实现树形结构遍历,最适合 employees 表的员工 - 经理层级关系。

先确认环境:使用 Oracle 自带 HR 用户,核心表 employees 字段:

  • employee_id:员工 ID
  • first_name || last_name:员工姓名
  • manager_id:直属经理 ID(顶层总裁为 NULL)
  • job_id:职位

基础概念

  1. LEVEL:表示层级数(根节点 = 1,子节点 = 2,孙节点 = 3...)
  2. CONNECT BY PRIOR 子字段 = 父字段:定义层级关系
  3. START WITH:指定根节点(顶层数据)

练习 1:基础层级查询(员工层级树)

需求

查询所有员工的层级、姓名、经理 ID,从总裁开始展示完整组织架构。

复制代码
-- 员工层级树查询
SELECT
  LEVEL AS 层级,
  employee_id AS 员工ID,
  first_name || ' ' || last_name AS 员工姓名,
  manager_id AS 经理ID
FROM hr.employees
-- 根节点:经理ID为空(总裁)
START WITH manager_id IS NULL
-- 层级关系:当前员工的经理ID = 上级员工的员工ID
CONNECT BY PRIOR employee_id = manager_id
-- 按层级排序
ORDER SIBLINGS BY employee_id;

关键说明

  • LEVEL 自动生成 1、2、3... 代表组织层级
  • PRIOR employee_id:上一级的员工 ID(经理)
  • 根节点:manager_id IS NULL(公司总裁)

练习 2:格式化层级展示(缩进显示树形结构)

需求

用空格缩进直观展示树形层级,更易读。

复制代码
-- 格式化树形展示
SELECT
  LEVEL AS 层级,
  -- 用 LEVEL-1 个空格缩进,模拟树形
  LPAD(' ', 2 * (LEVEL - 1)) || first_name || ' ' || last_name AS 树形员工姓名,
  employee_id,
  manager_id
FROM hr.employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id
ORDER SIBLINGS BY employee_id;

练习 3:筛选指定层级(仅查询 2 级经理)

需求

只查询第 2 层级的员工(直接向总裁汇报的经理)。

复制代码
-- 筛选指定层级
SELECT
  LEVEL AS 层级,
  employee_id,
  first_name || ' ' || last_name AS 员工姓名,
  job_id
FROM hr.employees
WHERE LEVEL = 2  -- 只保留2级员工
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;

练习 4:查询指定员工的所有下属

需求

查询员工 King(员工 ID 100)的所有下级员工(包含子、孙层级)。

复制代码
-- 查询指定员工的全部下属
SELECT
  LEVEL AS 下属层级,
  employee_id,
  first_name || ' ' || last_name AS 下属姓名,
  manager_id
FROM hr.employees
-- 根节点:King
START WITH employee_id = 100
-- 下属关系:当前员工的经理ID = 上级员工ID
CONNECT BY PRIOR employee_id = manager_id;

练习 5:查询指定员工的所有上级(向上递归)

需求

查询员工 Austin(员工 ID 105)的所有经理(从直属到总裁)。

复制代码
-- 向上递归查询所有上级
SELECT
  LEVEL AS 上级层级,
  employee_id,
  first_name || ' ' || last_name AS 上级姓名
FROM hr.employees
-- 根节点:Austin
START WITH employee_id = 105
-- 向上关联:当前员工的经理ID = 上级员工的ID
CONNECT BY PRIOR manager_id = employee_id;

练习 6:统计每层级员工数量

需求

统计公司每个层级有多少名员工。

复制代码
-- 按层级统计人数
SELECT
  LEVEL AS 层级,
  COUNT(*) AS 员工数量
FROM hr.employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id
GROUP BY LEVEL
ORDER BY 层级;

练习 7:CONNECT_BY_ROOT / CONNECT_BY_ISLEAF 进阶函数

1. CONNECT_BY_ROOT:获取根节点(顶层总裁)

复制代码
-- 每个员工 + 对应的顶层总裁
SELECT
  LEVEL AS 层级,
  first_name || ' ' || last_name AS 员工姓名,
  -- 根节点(顶层总裁)姓名
  CONNECT_BY_ROOT (first_name || ' ' || last_name) AS 顶层总裁
FROM hr.employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;

2. CONNECT_BY_ISLEAF:判断是否为叶子节点(无下属)

复制代码
-- 标记是否为最底层员工(无下属)
SELECT
  employee_id,
  first_name || ' ' || last_name AS 员工姓名,
  -- 1=叶子节点(无下属),0=非叶子(有下属)
  CONNECT_BY_ISLEAF AS 是否底层员工
FROM hr.employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;

核心语法总结

复制代码
SELECT LEVEL, 字段...
FROM 表
START WITH 根节点条件
CONNECT BY PRIOR 子节点字段 = 父节点字段
ORDER SIBLINGS BY 排序字段;

总结

  1. LEVEL 是层级编号,根节点固定为 1
  2. START WITH 定义从哪个节点开始遍历
  3. CONNECT BY PRIOR 定义父子关联关系
  4. 适合:组织架构、树形分类、递归遍历场景
相关推荐
这个DBA有点耶15 分钟前
Change Buffer深入:二级索引写入的隐形加速器与它的代价
数据库·mysql·代码规范
for_ever_love__20 分钟前
MySQL 事务隔离级别讲透:MVCC、幻读与四个级别怎么选
java·数据库·mysql·事务·mvcc·不可重复读·幻读
Knight_AL1 小时前
PostgreSQL Docker 数据库备份:pg_dump 与 SQL 格式备份的区别
数据库·docker·postgresql
写后端的胖头鱼1 小时前
Redis 的 RDB 和 AOF
java·数据库·redis
杨云龙UP1 小时前
Oracle 19c ADG 实时同步故障排查与修复:Standby Redo Log(SRL)文件缺失导致备库仅在主库归档后同步
数据库·oracle·adg·data guard·srl·ora-00313·ora-27037
步行cgn2 小时前
MySQL 报错:Access denied for user ‘root‘@‘localhost‘ 详解
java·数据库·spring
for_ever_love__3 小时前
Redis 数据类型全景:五种基础类型怎么用、什么时候用
数据库·redis·数据类型·hash·使用场景·zset·排行榜
SmartSoftHelp开发辅助优化3 小时前
SmartSoftHelp DeepCore XSuite Pro Global Eco AIAgent 2026.V29 专业国际版
数据库·oracle
honsor3 小时前
以太网温湿度传感器:RJ45直连机房的环境监控新方案
运维·网络·数据库·物联网·安全·云计算·github
西索斯coding3 小时前
Kimi k2.7-code-highspeed 接入 Cline 教程:baseURL 路由变更 + model_id 正确写法
java·服务器·数据库·ai