mysql递归查询语法WITH RECURSIVE的使用

 更新时间:2025年05月09日 10:23:39   作者:小玉起起  
本文主要介绍了mysql递归查询语法WITH RECURSIVE的使用,WITH RECURSIVE用于执行递归查询,特别适合处理层级结构或递归数据,具有一定的参考价值,感兴趣的可以了解一下

WITH RECURSIVE 是 SQL 中用于执行递归查询的语法,特别适合于处理层级结构或递归数据(如树形结构、图结构)。递归查询可以反复引用自己来查询多层次的数据,而无需写多个嵌套查询。

基本语法结构:

WITH RECURSIVE CTE_name AS (
    -- 基础查询部分 (非递归部分)
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition

    UNION ALL

    -- 递归查询部分
    SELECT column1, column2, ...
    FROM table_name t
    JOIN CTE_name cte ON t.column = cte.column
    WHERE condition
)
SELECT * FROM CTE_name;

关键部分解析:

  • WITH RECURSIVE

    • WITH 用于创建公共表表达式(CTE),RECURSIVE 关键字标识这是一个递归查询。
    • CTE_name 是你为公共表表达式(CTE)起的名字,后续查询可以引用它。
  • 基础查询(非递归部分):

    • 这是递归查询的起点,用于查询层级结构中的根数据(通常是最上层或最初始的数据)。
    • 通常,这部分查询会返回一个起始集合或基础条件,如树形结构中的根节点。
  • 递归查询部分:

    • 递归查询部分通常会参考(引用)上面基础查询的结果,形成一个不断迭代的过程。
    • 在递归查询部分中,常常会使用 JOIN 或者自连接来与 CTE_name(即递归查询的结果集)进行连接,查找下级数据。
    • 递归查询会逐步深入,直到没有更多的数据为止。
  • UNION ALL

    • UNION ALL 用于将基础查询(非递归部分)和递归查询部分合并成一个完整的结果集。
    • UNION ALL 不会去重(不同于 UNION),通常用于递归查询,以保持所有结果。
  • 最终查询:

    • 查询 CTE_name,得到递归查询的最终结果。
    • 递归查询的结果会返回所有层次的数据,直到没有更多的层级为止。

递归查询的工作流程:

  • 第一次迭代:

    • 执行基础查询部分,返回初始的数据集(通常是最顶层的数据)。
  • 第二次及后续迭代:

    • 递归查询部分会基于前一次查询的结果继续进行,查找下一级的数据(比如查找所有根节点的子节点)。
    • 每一轮迭代都会向结果集中添加新的行。
  • 停止条件:

    • 当递归查询找不到更多符合条件的行时,递归查询停止,返回最终的结果。

示例:员工与经理的层级关系

假设有一个员工表,每个员工有一个 manager_id 字段指向他们的经理,我们希望查询某个员工及其所有上级经理,直到最顶层的经理为止。

WITH RECURSIVE EmployeeHierarchy AS (
    -- 基础查询部分:查找某个特定员工
    SELECT id, name, manager_id
    FROM employees
    WHERE id = :employee_id  -- 查找指定员工

    UNION ALL

    -- 递归查询部分:查找员工的经理
    SELECT e.id, e.name, e.manager_id
    FROM employees e
    JOIN EmployeeHierarchy eh ON e.id = eh.manager_id
)
-- 返回所有员工及其上级经理
SELECT * FROM EmployeeHierarchy;

解释:

  • 基础查询部分:

    • 查找特定员工(通过 id = :employee_id)。
  • 递归查询部分:

    • 通过自连接 JOIN EmployeeHierarchy eh ON e.id = eh.manager_id 查找该员工的经理(manager_id 字段指向的员工)。
  • UNION ALL

    • 合并基础查询部分(初始员工)和递归查询部分(逐级向上查找经理)。
  • 查询最终结果:

    • 返回递归查询的结果,即该员工及其所有上级经理。

示例:树形结构的数据(如分类)

假设有一个包含分类的表 categories,每个分类有一个 parent_id 字段指向其父分类。我们希望查询某个分类及其所有的子分类。

WITH RECURSIVE CategoryHierarchy AS (
    -- 基础查询部分:查找某个特定分类
    SELECT id, name, parent_id
    FROM categories
    WHERE id = :category_id  -- 查找指定分类

    UNION ALL

    -- 递归查询部分:查找分类的子分类
    SELECT c.id, c.name, c.parent_id
    FROM categories c
    JOIN CategoryHierarchy ch ON c.parent_id = ch.id
)
-- 返回所有分类及其子分类
SELECT * FROM CategoryHierarchy;

解释:

  • 基础查询部分:

    • 查找指定的分类(通过 id = :category_id)。
  • 递归查询部分:

    • 查找所有子分类,JOIN 操作通过 c.parent_id = ch.id 来连接父分类和子分类。
  • UNION ALL

    • 合并基础查询和递归查询部分,逐层查找所有子分类。

递归查询的特性:

  • 递归深度限制:

    • 大多数数据库系统(如 PostgreSQL、MySQL 等)会对递归查询的深度进行限制,防止无限递归。MySQL 默认为 1000 层深度,但可以通过配置来调整此值。
  • 性能问题:

    • 递归查询可能会消耗较多的资源,特别是当层级较多或数据量庞大时。需要小心使用,避免导致性能瓶颈。
  • 迭代过程:

    • 递归查询通过每一轮的迭代逐步向下查询,直到没有更多数据。每一轮迭代的结果都会在下次查询中被引用。

总结:

  • WITH RECURSIVE 适用于处理层级结构或递归关系的数据,允许在查询中反复引用自己,查找多层次的数据。
  • 它由基础查询(非递归部分)和递归查询部分组成,通过 UNION ALL 连接两部分,逐步展开结果。
  • 使用递归查询时,需要注意递归深度限制和性能影响。

到此这篇关于mysql递归查询语法WITH RECURSIVE的使用 的文章就介绍到这了,更多相关mysql WITH RECURSIVE内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • SQL替换字符串值的5种常用方法

    SQL替换字符串值的5种常用方法

    这篇文章主要给大家介绍了关于SQL替换字符串值的5种常用方法,常用SQL的朋友应该知道,SQL中一般都会提供一些字符串处理函数,需要的朋友可以参考下
    2023-08-08
  • MySQL主从复制的原理图解及Java语言示例使用

    MySQL主从复制的原理图解及Java语言示例使用

    这篇文章主要介绍了MySQL的主从复制原理详细分析,读写分离是基于主从复制来实现的。文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • MySql8.023安装过程图文详解(首次安装)

    MySql8.023安装过程图文详解(首次安装)

    这篇文章主要介绍了MySql8.023安装过程(首次安装),本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • pymysql.err.DataError:(1264, ")异常的有效解决方法(最新推荐)

    pymysql.err.DataError:(1264, ")异常的有效解决方法(最新推荐)

    遇到pymysql.err.DataError错误时,错误代码1264通常指的是MySQL数据库中的Out of range value for column错误,这意味着你尝试插入或更新的数据超过了对应数据库列所允许的范围,这篇文章主要介绍了pymysql.err.DataError:(1264, ")异常的有效问题,需要的朋友可以参考下
    2024-05-05
  • 基于MySQL数据库的数据约束实例及五种完整性约束介绍

    基于MySQL数据库的数据约束实例及五种完整性约束介绍

    今天小编就为大家分享一篇关于基于MySQL数据库的数据约束实例及五种完整性约束介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 教你为MySQL数据库换挡加速

    教你为MySQL数据库换挡加速

    如果你是个赛车手,并且按一下按钮就能够立即更换引擎而不需要把车开到车库里去换,那会是什么感觉呢?MySQL数据库为开发人员所做的就好像是按按钮换引擎;它让你选择数据库引擎,并给你一条简单的途径来切换它。
    2010-02-02
  • MySQL百万级数据量分页查询方法及其优化建议

    MySQL百万级数据量分页查询方法及其优化建议

    这篇文章主要介绍了MySQL百万级数据量分页查询方法及其优化建议,帮助大家更好的处理MySQL数据库,感兴趣的朋友可以了解下
    2020-08-08
  • MySQL深分页问题原理与三种解决方案

    MySQL深分页问题原理与三种解决方案

    本文主要介绍了MySql深分页问题原理与解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • MySQL命令行下18个常用命令

    MySQL命令行下18个常用命令

    在日常的网站维护和MYSQL数据库管理中,会用到非常多的MYSQL命令,下面给大家介绍18个管理MYSQL数据库时最常使用的命令
    2018-03-03
  • MySQL存储数据乱码的问题解析

    MySQL存储数据乱码的问题解析

    这篇文章主要介绍了MySQL存储数据乱码的问题解析,作者从实际使用中的多个方面定位其原因然后解决,需要的朋友可以参考下
    2015-05-05

最新评论