MySQL with recursive 用法浅析
目录
写在前面
语句功能
with recursive 语法讲解
细节补充
“union all”语句
添加递归终止条件
写在前面
介绍“with recursive”用法的文章不少,但我都觉得讲的不够通俗,所以干脆自己写一篇。话不多说,进入正题。
语句功能
with recursive用于在MySQL中进行递归查询,另外由于树形结构的数据存储,在进行查询时,就是通过递归来实现的,所以很多人接触with recursive就是由于要对树形结构的数据进行查询。但你还是要区分清楚,with recursive并不局限于树形结构的查询,而是只要你需要递归查询,就可以用他。
with recursive 语法讲解
首先吐槽一下,MySQL的with recursive之所以让人在第一次接触的时候感觉不好理解,我个人觉得主要是他这个语法的设计问题,说白了就是这个语法看起来就让人感觉很迷惑,你要是接触过oracle那个递归查询的语法,会发现语法非常精简,很“见名知意”,属于那种几乎不用学习,你看别人写的一个例子,就可以模仿实现自己的需求的。接下来开始讲解,我们先来看个例子。
假设现在有一个公司里的部门信息表,名字叫“department”,除了存放部门信息外,也存储了表的层级关系,大概是这样的:
| id | name | parent_id | level |
|---|---|---|---|
| 1 | 总经理 | 1 | |
| 2 | 总经理办公室 | 1 | 2 |
| 3 | 研发部 | 1 | 2 |
| 4 | 人事部 | 2 | 3 |
| 5 | 采购部 | 2 | 3 |
| 6 | java开发部 | 3 | 3 |
| 7 | 前端开发部 | 3 | 3 |
“parent_id”表示当前节点的父节点的id,“level”表示当前节点所在的层级,如果对上面这张表进行递归查询,语法是这样的:
with recursive t1 as (select * from department where id = '3'union allselect * from department t2 inner join t1 on t1.id = t2.parent_id
)select * from t1;
这个语句表示从研发部开始,查询研发部的所有子节点,直到树的底部。如果想查询整张表,那就需要从根节点开始,把条件改为“id = '1'”,由于总经理是根节点,就相当于查询整张表。
接下来讲解这个语法,首先“with recursive”的语法有一部分是基本固定的:
with recursive t1 as (union all)select * from t1;
上面这个结构是基本固定的,这个临时表名“t1”你可以改成什么a1、b1、c2都可以,只要用到临时表名的地方一起改就行。剩下的主要就是“union all”上下的两句sql怎么写,在这之前,我们先来看一下,抛开sql语句,单纯的在一棵树里面进行一次递归查询的逻辑是怎样的:
先选中一个节点,查询该节点的所有子节点(假设有n个子节点),然后,再查询这n个子节点的所有子节点(假设有m个子节点),一直循环(也就是递归),到什么时候结束呢,到树的底部,或者你也可以指定查询到某一层。
当然这种从上往下查的看起来相对复杂一点,递归也可以从下往上查,这样简单一些,那么逻辑就是:
先选中一个节点,查询该节点的父节点,然后,继续查询这个父节点的父节点,一直循环(也就是递归),直到树的根节点,或者也可以指定查询到某一层。
不论从上往下查,还是从下往上查,这里面的关键信息有三个:
- 选中一个节点,也就是递归的起点;
- 查询这个节点的下一个节点(如果是从上往下查,就是子节点,如果是从下往上查,就是父节点),但是数据库怎么知道下一个节点是谁呢,这个你才知道,你要告诉数据库,两个节点之间的关联条件;
- 查到哪里结束,也就是递归的终点。
现在我们再重新看“with recursive”的语法:
with recursive t1 as (//语句1select * from department where id = '3'union all//语句2select * from department t2 inner join t1 on t1.id = t2.parent_id
)select * from t1;
说明:
语句1:是在说明递归的起点,这里就指定从研发部开始递归。
语句2:是在说明当前节点和下一个节点的关联条件,注意看他是怎么表达两个节点的关联条件的,是以连接查询的语法来表达两个节点的关联条件,使用最外层的“with recursive t1”定义的临时表名“t1”来表示当前节点所在的表,另外一个“department”则表示下一个节点所在的表。这条语句本身是从上往下查,所以最后的关联条件就是当前表的id值等于下一张表的parent_id值。
递归的终点在哪呢?上面的例子没有指定递归的重点,所以实际会一直查询到树的底部,如果想指定递归的终点,则是在语句2中指定,像下面这样就是通过表里的某个字段来指定递归的终点:
select * from department t2 inner join t1 on t1.id = t2.parent_id where t2.level < 4;
到此,with recursive 的基本用法就讲解完毕了,注意一下,整个“with as recursive t1 ()”语句都只是在定义递归的逻辑,最下面那行“select * from t1”才是真正的在执行查询,你别把最后这行给漏掉了。
接下来我们验证一下你是否真的学会了。如果你真的理解了“with recursive”的语法,那么上述例子当中的那张表,如果把需求改成从下往上查,你应当能看懂下面的查询语句:
with recursive t1 as (//语句1select * from department where id = '3'union all//语句2select * from department t2 inner join t1 on t1.parent = t2.id
)select * from t1;
语句1:并没有做修改,因为不需要改变递归的起点,只是需求由查询研发部的所有子节点,改成了查询研发部的所有父节点。
语句2:唯一的改动点就在这里,最后面的关联条件给改了,既然是从下往上查,那么应当是当前表的parent_id字段和下一张表的id字段关联。
细节补充
“union all”语句
注意一下递归查询里面的union all语句是遵循union all的语法的,也就是他上下两个语句里面的列是要一致的,以上述那张表为例,如果你不使用“*”,而是指定列的话,两条语句指定的列是需要一致的:
with recursive t1 as (//语句1select id, name, parent_id from department where id = '3'union all//语句2select t2.id, t2.name, t2.parent_id from department t2 inner join t1 on t1.id = t2.parent_id
)select * from t1;
添加递归终止条件
最后在补充一个带了递归终止条件的SQL语句示例:
with recursive t1 as (//语句1select id, name, parent_id from department where id = '3'union all//语句2select t2.id, t2.name, t2.parent_id from department t2 inner join t1 on t1.id = t2.parent_idwhere t2.level < 4
)select * from t1;
结束,goodbye。
相关文章:
MySQL with recursive 用法浅析
目录 写在前面 语句功能 with recursive 语法讲解 细节补充 “union all”语句 添加递归终止条件 写在前面 介绍“with recursive”用法的文章不少,但我都觉得讲的不够通俗,所以干脆自己写一篇。话不多说,进入正题。 语句功能 with r…...
ROS2常用命令集合
文章目录 指令帮助创建功能包功能包查找编译执行节点查看话题服务命令接口命令动作命令参数命令录制控制命令 指令帮助 ros2 --help # 帮助查看命令创建功能包 ros2 pkg create 包名 --build-type 构建类型 --dependencies 依赖列表 --node-name 可执行程序名称功能包查找 …...
VUE 子组件可以直接改变父组件的数据吗
子组件不可以直接改变父组件的数据。在Vue中,数据流是单向的,即父组件通过props向子组件传递数据,而子组件不能直接修改父组件的数据。这是为了维护数据流动的单向性和数据的可维护性。 如果子组件需要修改父组件的数据…...
Redis 持久化详解
AOF 持久化 AOF持久化数据恢复相对RDB慢,文件也更大,但数据丢失的风险更小。 AOF 写入 将数据写入Redis内存后,将写数据的命令记录到AOP磁盘文件。 【结构】server.aof_buf 主线程写操作执行完之后,命令会先追加到 Redis 的 se…...
基于riscv64架构的Dayu800开发板的napi_demo开发介绍
itopen组织1、提供OpenHarmony优雅实用的小工具2、手把手适配riscv qemu linux的三方库移植3、未来计划riscv qemu ohos的三方库移植 小程序开发4、一切拥抱开源,拥抱国产化 一、环境准备工作 1.1 Ubuntu20.04环境配置 如果已经配置OpenHarmony的编译环境则…...
HAL STM32 SPI/ABZ/PWM方式读取MT6816磁编码器数据
HAL STM32 SPI/ABZ/PWM方式读取MT6816磁编码器数据 📚MT6816相关资料(来自商家的相关资料): 资料:https://pan.baidu.com/s/1CAbdLBRi2dmL4D7cFve1XA?pwd8888 提取码:8888📍驱动代码编写&…...
HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 多选题序号5
基础认证题库请移步:HarmonyOS应用开发者基础认证题库 注:有读者反馈,题库的代码块比较多,打开文章时会卡死。所以笔者将题库拆分,单选题20个为一组,多选题10个为一组,题库目录如下,…...
Tekion 选择 ClickHouse Cloud 提升应用性能和指标监控
本文字数:4187;估计阅读时间:11 分钟 作者:ClickHouse team 本文在公众号【ClickHouseInc】首发 Tekion 由前 Tesla CIO Jay Vijayan 于 2016 年创立,利用大数据、人工智能和物联网等技术,为其汽车客户解决…...
mysql之触发器的使用
cr一:创建goods表和orders表; mysql> use mydb16_tirgeer Database changed mysql> create table goods(-> gid char(8) primary key,-> name varchar(10),-> price decimal(8,2),->-> num int); Query OK, 0 rows affected (0.0…...
使用Java和Hazelcast实现分布式数据存储
使用Java和Hazelcast实现分布式数据存储 大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在分布式系统中,实现高效的数据存储和管理是非常重要的。Hazelcast作为一个内存数据网格(IMDG)&…...
Hi3751V560_SELinux
Hi3751V560_SELinux setenforce Enforcing setenforce Permissive(或“setenforce 0”) getenforce V560:demo本身的: [ 13.765161] type=1400 audit(1628821512.905:4): avc: denied { read } for pid=1926 comm="system_server" name="ifindex" d…...
邮件安全篇:邮件反垃圾系统运作机制简介
1. 什么是邮件反垃圾系统? 邮件反垃圾系统是一种专门设计用于检测、过滤和阻止垃圾邮件的技术解决方案。用于保护用户的邮箱免受未经请求的商业广告、诈骗信息、恶意软件、钓鱼攻击和其他非用户意愿接收的电子邮件的侵扰。 反垃圾系统的常见部署形式 2. 邮件反垃圾…...
LoRaWAN设备的两种入网方式(ABP和OTAA)
目录 一、OTAA 1、名词解释 2、入网流程 二、ABP 三、两种入网方式的比较 一、OTAA 1、名词解释 (1)AppEUI:64位(8字节)的唯一标识符,用于标识特定的应用程序或组织(如果用的是chirpstac…...
【Rust光年纪】极致性能与灵活选择:Rust语言数学优化库详解
Rust语言中的数学优化:六大利器汇总 前言 在当今信息时代,数据处理和数学优化成为了各行各业中不可或缺的重要环节。为了满足对高效、快速计算的需求,Rust语言逐渐成为了许多开发者的首选,因其性能优越、并发安全等特点。本文将…...
机器学习 | 回归算法原理——最小二乘法
Hi,大家好,我是半亩花海。很早便想学习并总结一本很喜欢的机器学习图书——立石贤吾的《白话机器学习的数学》,可谓通俗易懂,清晰形象。那就在此分享并作为学习笔记来记录我的学习过程吧!本章的回归算法原理基于《基于…...
.NET Core 中的字符串压缩方法
字符串压缩的概念 字符串压缩通常指的是通过算法减少字符串表示所需的数据量,同时保持字符串的原始信息或能够无损地恢复原始字符串。这种压缩可以是针对文本数据的特定算法,也可以是更通用的数据压缩算法。 .NET Core 中的字符串压缩方法 使用数据压…...
SQL 基础知识
SQL(结构化查询语言)是一种用于管理和操作关系数据库的标准编程语言。以下是一些 SQL 的基础知识: 基本概念 数据库(Database): 存储和管理数据的容器。一个数据库可以包含多个表。 表(Table&…...
【数据结构初阶】单链表经典算法题十二道——得道飞升(上篇)
目录 1、移除元素 2、反转链表 3、链表的中间节点 4、合并两个有序链表 Relaxing Time!!! ———————————————— 天气之子幻 ———————————————— 1、移除元素 思路: 创建一个新链表࿰…...
Python爬虫技术 第16节 XPath
XPath是一种在XML文档中查找信息的语言,尽管XML和HTML在语法上有区别,但XPath同样适用于HTML文档的解析,尤其是在使用如lxml这样的库时。XPath提供了一种强大的方法来定位和提取XML/HTML文档中的元素和属性。 XPath基础 XPath表达式由路径表…...
本地部署,Whisper: 开源语音识别模型
目录 简介 特点 应用 使用方法 总结 GitHub - openai/whisper: Robust Speech Recognition via Large-Scale Weak SupervisionRobust Speech Recognition via Large-Scale Weak Supervision - openai/whisperhttps://github.com/openai/whisper 简介 Whisper 是一个由 O…...
告别Salesforce!这5个开源AI CRM项目,帮你用更低成本打造专属客户管理系统
开源AI CRM革命:5个低成本替代方案深度评测与技术选型指南 当Salesforce的年费账单突破六位数时,越来越多的技术决策者开始将目光转向开源生态。这不是简单的成本妥协,而是一场关于数据主权、技术栈控制和AI原生体验的范式转移。以下是经过三…...
【AI工具篇】10款免费AI聊天与绘画神器:从GPT到Stable Diffusion的全方位体验
1. GPT机器人:全能型AI助手 这款工具可以说是AI领域的瑞士军刀,既能陪你聊天又能帮你画画。我实测下来最惊艳的是它直接集成了GPT-4模型,要知道很多收费工具都还在用3.5版本。打开应用就像有个学霸朋友随时待命——上周我写项目方案卡壳时&am…...
5分钟搞定Meson交叉编译:手把手教你配置ARM64目标平台(附DPDK实例)
Meson交叉编译实战指南:从零构建ARM64平台的DPDK应用 第一次接触交叉编译时,我盯着满屏的工具链路径和架构参数发愣——这简直像在解译外星密码。直到发现Meson的交叉编译配置文件,才发现原来构建跨平台应用可以如此优雅。本文将带你用Meson这…...
vue3-composition-admin TypeScript最佳实践:类型安全与开发效率的完美平衡
vue3-composition-admin TypeScript最佳实践:类型安全与开发效率的完美平衡 【免费下载链接】vue3-composition-admin 🎉 基于vue3 的管理端模板(Vue3 TS Vuex4 element-plus vue-i18n-next composition-api) vue3-admin vue3-ts-admin 项目地址: http…...
【Python内存管理2026权威白皮书】:GIL演进、引用计数重构与GC智能调度三大突破性策略首次公开
第一章:Python智能体内存管理策略2026最新趋势全景概览随着大语言模型驱动的Python智能体(Agent)在生产环境中的深度部署,传统CPython内存管理机制正面临前所未有的挑战:动态工具调用、多轮推理缓存、跨Agent状态共享及…...
OpenClaw安全实践:GLM-4.7-Flash本地化部署的权限控制指南
OpenClaw安全实践:GLM-4.7-Flash本地化部署的权限控制指南 1. 为什么需要关注OpenClaw的权限控制? 去年夏天,我在整理电脑上的财务报告时,无意中发现OpenClaw自动将我的税务文件同步到了一个陌生目录。这个意外让我意识到——当…...
OpenClaw:AI 权限治理的核心问题
子玥酱 (掘金 / 知乎 / CSDN / 简书 同名) 大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚…...
本地图片检索新方案:ImageSearch完全使用指南
本地图片检索新方案:ImageSearch完全使用指南 【免费下载链接】ImageSearch 基于.NET8的本地硬盘千万级图库以图搜图案例Demo和图片exif信息移除小工具分享 项目地址: https://gitcode.com/gh_mirrors/im/ImageSearch 当你的电脑中存储了成千上万张图片&…...
OpenClaw可视化监控:为nanobot任务添加Web仪表盘
OpenClaw可视化监控:为nanobot任务添加Web仪表盘 1. 为什么需要可视化监控? 去年夏天,我部署了一个基于OpenClaw的nanobot自动化任务,用于定时抓取行业动态并生成日报。最初几周运行良好,直到某天早上发现连续三天的…...
设计师必看:Photoshop混合模式实战指南,5分钟搞定光影合成与氛围感调色
Photoshop混合模式实战指南:5分钟掌握光影合成与氛围调色 当你在深夜赶稿时,突然发现人物照片缺乏立体感,或是产品静物图需要增强戏剧性光影——这就是混合模式大显身手的时刻。不同于繁琐的曲线调整和复杂的蒙版操作,混合模式就像…...
