SQL 递归 ---- WITH RECURSIVE 的用法

ops/2025/1/23 23:34:58/

SQL 递归 ---- WITH RECURSIVE 的用法

开发中遇到了一个需求,传递一个父类id,获取父类的信息,同时获取其所有子类的信息。 首先想到的是通过程序中去递归查,但这种方法着实孬了一点,于是想,sql能不能递归查询呢? 这不,一查发现还真能

一 、说明

WITH RECURSIVE 是 SQL 中的一个强大特性,通常用于处理递归查询,常见于 PostgreSQL、MySQL 8.0 及以上、SQL Server 等数据库系统。它允许你在一个查询中引用其自身的结果集,这对于处理具有层次结构的数据(如树状结构或图结构)非常有用。

二、 语法

sql">WITH RECURSIVE tmp_table (column_list) AS (-- 初始查询(非递归部分)initial_queryUNION (ALL)-- 递归查询部分recursive_query
)
SELECT * FROM tmp_table;
  • WITH RECURSIVE:递归关键字
  • tmp_table:可以理解为一个临时表
  • column_list:定义 结果集中的列列表,也可省略
  • initial_query:初始查询,它是递归的基础,通常是一个非递归的查询,为递归查询提供起始数据。
  • UNION ALL:将初始查询和递归查询的结果集合并。注意,使用 UNION ALL 是为了保留重复行,而 UNION 会去除重复行。
  • recursive_query:递归查询部分,会引用 tmp_table 自身的结果集。

三、 举例说明

  • 建表,初始化一部分数据 (数据库环境 : MYSQL 8.0 以上)

    sql">CREATE TABLE `geographic_info` (`id` int NOT NULL AUTO_INCREMENT COMMENT '自增编号',`name` varchar(20) NOT NULL COMMENT '名称',`parent_id` int  NULL COMMENT '父节点id',PRIMARY KEY (`id`)
    ) COMMENT='地理信息表';-- init data
    insert into geographic_info(id,name,parent_id) value (1,'安徽省',null);
    insert into geographic_info(id,name,parent_id) value (2,'合肥市',1);
    insert into geographic_info(id,name,parent_id) value (3,'高新区',2);
    insert into geographic_info(id,name,parent_id) value (4,'某某小区',3);
    

  • 创建递归查询

    sql">-- 自下而上进行递归
    -- 通过某某小区的id,查询出其父类及以上层级的数据
    WITH RECURSIVE descendants AS (SELECT gi.id, gi.name,gi.parent_id from geographic_info giWHERE gi.id = 4UNION SELECT gi.id, gi.name,gi.parent_id from geographic_info gi join descendants d on gi.id = d.parent_id
    )
    SELECT * FROM descendants order by id;
    
    • 返回数据
      在这里插入图片描述
    sql">-- 自上而下进行递归
    -- 通过安徽省的id,查询出其所有子类的数据(注:此处不合理查询请忽略,仅仅为了举例)
    WITH RECURSIVE descendants AS (SELECT gi.id, gi.name from geographic_info giWHERE gi.id = 1UNION SELECT gi.id, gi.name from geographic_info gi 
    join descendants d on gi.parent_id = d.id
    )
    SELECT * FROM descendants order by id;
  • 返回数据
    在这里插入图片描述

四、注意事项

  • 终止条件: 递归最需要关注的地方就是终止条件,处理不当就会导致无限递归。
  • 性能:对于深度较大的树结构或图结构,递归查询可能会影响性能。在某些情况下,使用其他存储方式(如闭包表)可能会更高效
  • 数据库支持:并非所有数据库都支持 WITH RECURSIVE。例如,MySQL 从 8.0 开始支持,而一些较旧的版本不支持,使用前请确认你的数据库是否支持。

五、写在最后

数据库递归的用法也是第一次学习,文章可能存在错误之处,还请指出,我们共同进步!

文章如果对您有用,就点个赞呗。
较旧的版本不支持,使用前请确认你的数据库是否支持。

五、写在最后

数据库递归的用法也是第一次学习,文章可能存在错误之处,还请指出,我们共同进步!

文章如果对您有用,就点个赞呗。


http://www.ppmy.cn/ops/152596.html

相关文章

深入理解Spring Boot:启动方式、注解、配置文件与模板引擎

引言 Spring Boot 是一个用于简化 Spring 应用初始搭建以及开发过程的框架。它通过约定大于配置的方式,大大减少了开发者需要编写的配置代码。本文将详细介绍 Spring Boot 的启动方式、核心注解的用法及含义、配置文件的书写格式以及模板引擎的使用方法。 Spring B…

kafka学习笔记2 —— 筑梦之路

KRaft模式 Kafka的KRaft模式是一种新的元数据管理方式,旨在去除对ZooKeeper的依赖,使Kafka成为一个完全自包含的系统。在Kafka的传统模式下,元数据管理依赖于ZooKeeper,这增加了部署和运维的复杂性。为了解决这个问题,…

设计模式:责任链模式——行为型模式

目录 主要角色 优点 缺点 适用场景 示例代码 普通写法: 策略模式: 总结对比 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求发送者与…

如何运用python爬虫获取大型资讯类网站文章,并同时导出pdf或word格式文本?

这里,我们以比较知名的商业新知网站https://www.shangyexinzhi.com/为例进行代码编写,下面进行代码应用思路。 第一部分,分析网站结构 首先,我们来分析,要使用Python技术分析一个网站的结构,通常可以通过…

如何构建一个简单的React应用?

如何构建一个简单的React应用? React 是由 Facebook 开发和维护的一个前端 JavaScript 库,广泛用于构建用户界面。React 采用组件化的设计思想,可以让开发者更加高效地构建动态的、交互性强的 Web 应用。本文将带你一步步构建一个简单的 Rea…

网络安全技术之网络安全

网络安全之物理安全策略 物理安全策略的目的是保护计算机系统、网络服务器、打印机等硬件实体和信链路免受自然灾害、人为破坏和搭线攻击;验证用户的身份和使用权限、防用户越权操作;确保计算机系统有一个良好的电磁兼容工作环境;建立完备的…

MySQL入门(数据库、数据表、数据、字段的操作以及查询相关sql语法)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

【Qt 常用控件】显示类控件——QLabel

目录 1.QLabel 1.1 textFormat 文本类型 普通文本和富文本 Markdown格式 1.2 alignment 文本对齐方式 1.3 wordWrap 自动换行 1.4 indent 文本缩进 1.5 margin 边距 1.6 buddy,qlabel伙伴 1.7 pixmap图片 和 scaledContents自动填充 1.QLabel 功能&#x…