【SQL 如何解锁递归】

前言

工作中这么多年了经常遇到树形结构的数据,之前涉及到数据结构的数据查询,我都是通过程序去组装

😂直到一天拥有20年经验的技术经理告诉我,SQL中有处理递归的语法😍

✈️今天就和大家一起学一下吧!

SQL中的递归语法

基本知识

  1. RECURSIVE 关键字 :在不同的数据库系统中,这个关键字的使用情况有所不同。像 PostgreSQL、MySQL 8.0 以及 SQLite 3.8.3 及以上版本,需要显式使用RECURSIVE关键字;而 SQL Server 和 Oracle 则不需要。
  2. 终止条件:递归查询必须包含一个能让递归停止的条件,防止出现无限循环。
  3. 性能方面:在处理大数据量时,递归 CTE(Common Table Expression,公共表表达式) 的效率可能会比较低,这种情况下可以考虑使用迭代方法或者数据库特定的函数。

RECURSIVE 测试

测试1:查询出某个节点下面所有的子节点

查询某个领导下面所有组织架构中的员工

1.创建表插入数据

SQL 复制代码
-- 创建 employees 表,manager_id 上级领导ID
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    manager_id INT, 
    FOREIGN KEY (manager_id) REFERENCES employees(employee_id)
);
复制代码
-- 插入示例数据
INSERT INTO employees (employee_id, name, manager_id) VALUES
(100, 'Alice', NULL),  -- Alice 是 CEO,没有上级
(101, 'Bob', 100),     -- Bob 向 Alice 汇报
(102, 'Charlie', 100), -- Charlie 向 Alice 汇报
(103, 'David', 101),   -- David 向 Bob 汇报
(104, 'Eve', 101),     -- Eve 向 Bob 汇报
(105, 'Frank', 102),   -- Frank 向 Charlie 汇报
(106, 'Grace', 103);   -- Grace 向 David 汇报

-- 继续插入
INSERT INTO employees (employee_id, name, manager_id) VALUES
(107, 'Heidi', 102),    -- Heidi 向 Charlie 汇报
(108, 'Ivan', 104),     -- Ivan 向 Eve 汇报
(109, 'Judy', 104),     -- Judy 向 Eve 汇报
(110, 'Kevin', 105),    -- Kevin 向 Frank 汇报
(111, 'Lisa', 105),     -- Lisa 向 Frank 汇报
(112, 'Mike', 107),     -- Mike 向 Heidi 汇报
(113, 'Nancy', 107),    -- Nancy 向 Heidi 汇报
(114, 'Oscar', 109),    -- Oscar 向 Judy 汇报
(115, 'Patty', 109),    -- Patty 向 Judy 汇报
(116, 'Quinn', 111),    -- Quinn 向 Lisa 汇报
(117, 'Ryan', 111),     -- Ryan 向 Lisa 汇报
(118, 'Sarah', 112),    -- Sarah 向 Mike 汇报
(119, 'Tom', 112),      -- Tom 向 Mike 汇报
(120, 'Uma', 115),      -- Uma 向 Patty 汇报
(121, 'Victor', 115),   -- Victor 向 Patty 汇报
(122, 'Wendy', 117),    -- Wendy 向 Ryan 汇报
(123, 'Xavier', 117),   -- Xavier 向 Ryan 汇报
(124, 'Yvonne', 120),   -- Yvonne 向 Uma 汇报
(125, 'Zach', 120);     -- Zach 向 Uma 汇报

2.查询指定领导下面所有的员工数据

复制代码
WITH RECURSIVE subordinates AS (
    SELECT employee_id, name, manager_id, 1 AS level
    FROM employees
    WHERE manager_id = 100  -- 初始查询:找出经理ID为100的直接下属
    
    UNION ALL
    
    SELECT e.employee_id, e.name, e.manager_id, s.level + 1
    FROM employees e
    JOIN subordinates s ON e.manager_id = s.employee_id
    -- 递归查询:找出每个下属的下属,直到没有下属为止
)
SELECT * FROM subordinates;

查询结果

测试2:查询某节点下面指定层级的数据

查询某个领导下2个层级组织架构中的员工

复制代码
WITH RECURSIVE subordinates AS (
    SELECT employee_id, name, manager_id, 1 AS level
    FROM employees
    WHERE manager_id = 100  -- 初始查询:找出经理ID为100的直接下属
    
    UNION ALL
    
    SELECT e.employee_id, e.name, e.manager_id, s.level + 1
    FROM employees e
    JOIN subordinates s ON e.manager_id = s.employee_id
		
		WHERE s.level < 2 --- 注意查询下面两级是<2,不是小于3
    
)
SELECT * FROM subordinates;

🧨注意:WHERE s.level < N表示递归到第N级时停止(实际返回1N级的数据)

测试3:只查询某个节点下面 指定层级的数据

查询某个领导下第3层级组织架构中的员工

复制代码
WITH RECURSIVE subordinates AS (
    SELECT employee_id, name, manager_id, 1 AS level
    FROM employees
    WHERE manager_id = 100  -- 初始查询:找出经理ID为100的直接下属
    
    UNION ALL
    
    SELECT e.employee_id, e.name, e.manager_id, s.level + 1
    FROM employees e
    JOIN subordinates s ON e.manager_id = s.employee_id    
)
SELECT * FROM subordinates WHERE LEVEL = 3;

😂哈哈哈,这种需求还真没遇到过

总结

通过本篇博客,我们知道了数据库中如何去使用递归。

当然如果不想用递归,我们可以维护一个冗余的路径字段,这样我们需要查询某个节点的所有下级时不用递归也能查询。当然这个字段我们每次在插入节点的时候就得去维护好👌

冗余路径字段:path:1.2.3(最后一位本级ID),这就意味这它的上级路径是 2--->1, 查询2的所有下级数据,就(path like'1.2.%')

希望本篇文章,能帮到你!感谢老铁一键三连!还有哪些好的方案,大家可以留言O😉

相关推荐
Warren989 分钟前
软件测试-Selenium学习笔记
java·javascript·笔记·学习·selenium·测试工具·安全
杨云龙UP11 分钟前
CentOS Linux 7 (Core)上部署Oracle 11g、19C RAC详细图文教程
数据库·oracle
ezl1fe23 分钟前
RAG 每日一技(十八):手写SQL-RAG太累?LangChain的SQL智能体(Agent)前来救驾!
数据库·人工智能·后端
小咖张29 分钟前
spring声明式事务,finally 中return对事务回滚的影响
数据库·java 声明式事务
JSON_L30 分钟前
MySQL 加锁与解锁函数
数据库·mysql
没有bug.的程序员35 分钟前
JVM 运行时数据区详解:内存模型与对象生命周期全景解析
java·jvm·运行时数据区·内存模型·对象生命周期
一语长情1 小时前
Netty流量整形:保障微服务通信稳定性的关键策略
java·后端·架构
盖世英雄酱581361 小时前
第一个RAG项目遇到的问题
java·spring boot
最初的↘那颗心1 小时前
Flink Stream API - 源码开发需求描述
java·大数据·hadoop·flink·实时计算
白鲸开源2 小时前
收藏!史上最全 Apache SeaTunnel Source 连接器盘点 (2025版),一篇通晓数据集成生态
大数据·数据库·开源