MySQL递归查询:洞悉数据的层层关联

在处理关系型数据库时,我们经常会遇到这样的情况:某些数据之间存在层级关系,例如目录、组织结构、评论等。在这些场景下,我们需要一种灵活的查询技术来处理这种层级关系。今天我们就来探讨MySQL中的递归查询,体验其独特的魅力,并展示两个实用的示例。

目录

一、递归查询简介

二、递归查询的基本语法

三、MySQL递归查询示例

四、递归查询的另一个应用


一、递归查询简介

递归查询是一种在数据库中处理具有层次结构的数据的方法,它使用带有自连接的表和公共表表达式(Common Table Expression,简称CTE),让我们可以在一个表中查询出具有父子关系的数据。在MySQL中,我们可以使用WITH RECURSIVE语句来实现递归查询。


二、递归查询的基本语法

在MySQL中,递归查询的基本语法如下:

WITH RECURSIVE cte_name (列1, 列2, ...) AS  (  -- 非递归部分,用于初始化cte(公共表表达式)SELECT 列1, 列2, ... FROM 表名 WHERE 初始查询条件UNION ALL  -- 递归部分,用于扩展cteSELECT 列1, 列2, ... FROM 表名 WHERE ...
)  
SELECT 列1, 列2, ... FROM cte_name;

WITH RECURSIVE:这是递归查询的关键字,用于定义递归查询。

cte_name:这是为递归查询定义的名称,方便后续引用。


三、MySQL递归查询示例

下面是一个简单的示例,演示如何使用MySQL进行递归查询。假设我们有一个包含员工和他们的上级的表,如下所示:​​​​​​​

CREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(100),manager_id INT,FOREIGN KEY (manager_id) REFERENCES employees (id)
);


插入测试数据:​​​​​​​

INSERT INTO employees (id, name, manager_id)
VALUES (1, '张三', NULL),(2, '李四', 1),(3, '王五', 2),(4, '赵六', 2),(5, '孙七', 3),(6, '周八', 3),(7, '吴九', 5),(8, '郑十', 6);


我们的需求是查找某个特定员工的所有下级。通过递归查询实现:

WITH RECURSIVE emp AS (SELECT id, name, manager_idFROM employeesWHERE name = '王五'UNION ALLSELECT e.id, e.name, e.manager_idFROM employees e, empWHERE e.manager_id = emp.id
)
SELECT id, name FROM emp;


得到的结果如图:

图片


这个示例中的查询它包含两个部分:非递归部分和递归部分。非递归部分是从员工表中选择某个员工,递归部分是通过与公共表表达式进行连接从员工表中选择下属员工。最后,从公共表表达式中查询整个员工层级结构。


四、递归查询的另一个应用

使用递归查询可以生成指定数量的序列,如下SQL生成1~10的序列:

WITH RECURSIVE seq(seq_no) AS (SELECT 1UNION ALLSELECT 1 + seq_no FROM seq WHERE seq_no < 10)
SELECT * FROM seq;

​​​​​​​
那么,生成这个序列有什么用呢?有很多场景需要用到这种序列,如:统计每年在校学生人数。

假设有一个招生人数表,记录了每年招生人数和学生学制等信息,现需要统计每年在校学生人数。

我们仍然使用Excel表格辅助分析,为该问题编写SQL,先在Excel里面输入样例数据:

图片

先统一约定,假设本例中的统计时间为下半年,即:某一入学年度的招生人数,会统计到在校人数中,当年毕业的学生,不会统计到在校人数中。

为了统计某一年在校学生人数,我们在该数据后面添加辅助数据,比如统计2023年在校学生人数,填入如下数据:

图片

学生在校状态,是根据入学年度和学制计算出毕业时间,然后与统计年度进行比较得出。筛选出状态为在校的数据然后求和即可。

但本次的需求是统计每年在校学生人数,也就是需要为每一个统计年度生成这样的数据,如下图所示:

图片

分析这些数据的规律,某一入学年度的数据,在入学年度及之后的每一个统计年度中,如果该入学年度的学生在校,则该数据需要出现在该统计年度中,学生在校多少年,该入学年度的数据就会出现多少次。而连续的统计年度,就是一个序列!

用以下SQL模拟招生人数表数据:

SELECT 2020 year, 300 enrollment, 3 length_of_schooling
UNION ALL SELECT 2021, 400, 4
UNION ALL SELECT 2022, 400, 4
UNION ALL SELECT 2023, 400, 4

​​​​​​​
将该数据与递归产生的序列连接,就可以得到前面需要的每一个统计年度的招生数据。为便于计算统计年度,序列从0开始,序列最大值为学制最大值:

WITH RECURSIVE seq(seq_no) AS (SELECT 0UNION ALLSELECT 1 + seq_no FROM seq WHERE seq_no < 4
), cnt AS (SELECT 2020 enro_year, 300 enrollment, 3 length_of_schoolingUNION ALL SELECT 2021, 400, 4UNION ALL SELECT 2022, 400, 4UNION ALL SELECT 2023, 400, 4)
SELECT cnt.*, enro_year + seq_no stat_year,IF(seq_no < length_of_schooling, '在校', '毕业') status
FROM cnt, seq
-- WHERE seq_no < length_of_schooling
ORDER BY enro_year + seq_no, enro_year;

​​​​​​​
只需要将上述SQL稍做修改,按统计年度分组统计,就可以得到每年的在校学生人数:

WITH RECURSIVE seq(seq_no) AS (SELECT 0UNION ALLSELECT 1 + seq_no FROM seq WHERE seq_no < 4
), cnt AS (SELECT 2020 enro_year, 300 enrollment, 3 length_of_schoolingUNION ALL SELECT 2021, 400, 4UNION ALL SELECT 2022, 400, 4UNION ALL SELECT 2023, 400, 4)
SELECT enro_year + seq_no stat_year, sum(enrollment) stu_enrollment 
FROM cnt, seq
WHERE seq_no < length_of_schooling
GROUP BY enro_year + seq_no
ORDER BY enro_year + seq_no;

​​​​​​​

得到的结果如图:

图片


通过使用递归查询,我们可以轻松地解决一些传统查询方法难以处理的问题。通过本文的介绍和示例,希望能够帮助大家更好地理解和应用MySQL中的递归查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/184899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yolov3学习总结

目标检测算法 单阶段&#xff1a;不提取出候选框&#xff0c;直接将整个图像输入模型中&#xff0c;算法直接输出检测结果&#xff0c;端到端 yolo&#xff0c;ssd 端到端&#xff0c;输入图像到网络中&#xff0c;然后从网络中输出图像 二阶段&#xff1a;先从图像中提取出…

紫光展锐Wi-Fi 6成功通过Wi-Fi联盟认证

近日&#xff0c;紫光展锐Wi-Fi 6产品成功通过Wi-Fi联盟 (简称“WFA”) Qualified Solution 认证&#xff0c;并支持Wi-Fi 6 Release 2&#xff0c;标志着紫光展锐自研Wi-Fi 6 IP技术已经成熟&#xff0c;在互操作性、安全性和一系列应用专有协议方面达到了国际行业标准。 WFA是…

自定义 element DatePicker组件指令 使选择器呈现为只读状态,用户无法直接编辑,但可以查看和选择日期

1.问题 现实中遇到列表的搜索条件使用DatePicker 组件进行开始结束时间筛选&#xff0c;但是手动修改input中的值&#xff0c;导致请求参数异常。比如讲clearable设置为false之后还是能手动清空输入框中的值。虽然组件提供了readonly 属性&#xff0c;但是也会让日期选择也无法…

【Flink进阶】-- Flink kubernetes operator 快速入门与实战

1、课程目录 2、课程链接 https://edu.csdn.net/course/detail/38831

4天肝出一个数据应用,可能吗?| StartDT Hackathon

以「基于SimbaOS Kernel的应用创新」为主题&#xff0c;2023年秋季StartDT Hackathon近日圆满收官。 本季黑客马拉松不仅有多次蝉联冠军的算法团队参战&#xff0c;有过去惜败的队伍卷土重来&#xff0c;还吸引到了制造、政企、泛零售等行业线开发者“攻擂”&#xff0c;携丰富…

uniapp + electron 打包项目

参考文献 1、控制台安装electron和electron打包工具electron-packager npm install electron -g npm install electron-packager -g2、manifest.json修改 运行的基础路径修改为&#xff1a;./ 不然打包出来会出现白屏&#xff0c;读取不到&#xff0c;因为打包出来的h5默认加…

【JavaEE】线程安全与线程状态

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

配电房综合监控系统

配电房综合监控系统是一种集成了实时监控、数据采集、远程控制等多功能的系统&#xff0c;用于对配电房进行全方位的监测和管理。 力安科技配电室综合监控系统依托电易云-智慧电力物联网&#xff0c;实现配电室环境监测、有害气体监测、安防监控、采暖通风、门禁、灯光、风机、…

进阶C语言-字符函数和字符串函数

字符函数和字符串函数 &#x1f388;1.函数介绍&#x1f50e;1.1strlen函数&#x1f52d;1.1.1strlen函数的模拟实现&#x1f4d6;1.计数器法&#x1f4d6;2.递归法&#x1f4d6;3.指针-指针 &#x1f50e;1.2strcpy函数&#x1f52d;1.2.1strcpy函数的模拟实现 &#x1f50e;1…

Linux系统编程 day07 信号

Linux系统编程 day07 信号 1. 信号的介绍以及信号的机制2. 信号相关函数2.1 signal2.2 kill2.3 abort和raise2.4 alarm2.5 setitimer 3. 信号集4. 信号捕捉函数6. SIGCHLD信号7. SIGUSR1与SIGUSR2 1. 信号的介绍以及信号的机制 信号是信息的载体&#xff0c;在Linux/Unix环境下…

如何有效的进行 E2E

一、前言 本文作者介绍了什么是E2E测试以及E2E测试测什么&#xff0c;并从对于被测系统、测试用例、测试自动化工具、测试者四个方面的要求&#xff0c;介绍了如何保证E2E测试有效性&#xff0c;干货满满&#xff0c;值得学习。 二、什么是E2E测试 相信每一个对自动化测试感…

需求不明确的情况下,测试该如何处理?

当需求不明确的情况下&#xff0c;测试团队可以采取以下措施来处理&#xff1a; 1. 与项目团队进行沟通&#xff1a;测试团队应与项目团队密切合作&#xff0c;与业务分析师、产品经理等相关人员进行沟通&#xff0c;以获取更多的需求细节和背景信息。通过与相关方的交流&…

zookeeper 客户端常用命令简单记录(实操课程系列--watcher功能测试)(发布订阅功能测试)

本系列是zookeeper相关的实操课程&#xff0c;课程测试环环相扣&#xff0c;请按照顺序阅读测试来学习zookeeper。阅读本文之前&#xff0c;请先阅读----zookeeper 单机伪集群搭建简单记录&#xff08;实操课程系列&#xff09; 1、命令行工具切换到zookeeper的bin目录下面&am…

springboot自定义校验注解的实现

自定义校验注解的实现 通过谷粒商城项目学习了自定义校验器的实现一、编写自定义校验注解二、自定义注解的校验器三、关联自定义的校验器和自定义的校验注解总结 通过谷粒商城项目学习了自定义校验器的实现 近日在学习雷神的谷粒商城项目&#xff0c;其中有一个自定义校验的实…

国外客户跟我要佣金,该给不该给?

“Jack&#xff0c;这次你要是不帮我&#xff0c;我就死定了&#xff01;” 收到美国公司采购Antony的信息时&#xff0c;我有些哭笑不得&#xff0c;因为在我电脑屏幕上除了他的信息外&#xff0c;还有来自他公司监察部门的邮件&#xff1a; “jack先生&#xff0c;我们调查…

二极管钳位电路的作用

1、使用钳位二极管的瞬态保护即将输出电压限定在某个区间 钳位二极管不仅仅是为了改变电压基线。它们在缓解瞬态事件方面非常有用&#xff0c;尤其是ESD和雷电浪涌。例如&#xff0c;当输入电压高于 Vh 时&#xff0c;D1 正向偏置。因此&#xff0c;过多的电流流过 D1 而不是负…

Linux Centos系统安装Mysql8.0详解

本文是基于服务器Linux Centos 8.0系统 安装 Mysql8.0真实运维工作实战为例&#xff0c;详细讲解安装的全过程。 1&#xff0c;检查卸载mariadb Mariadb数据库是mysql的分支&#xff0c;mariadb和mysql会有冲突&#xff0c;所以安装Mysql前&#xff0c;首先要检查是否安装了m…

java学习part23异常try catch

124-异常处理-异常的概述与常见异常的举例_哔哩哔哩_bilibili 1.异常 2.try catch 3.finally 类似golang的defer 一定执行的语句

7-1 哈夫曼树与哈夫曼编码

哈夫曼树与哈夫曼编码 题目描述输入格式输出格式输入样例输出样例 分数 30 作者 伍建全 单位 重庆科技学院 题目描述 哈夫曼树(Huffman Tree)又称最优二叉树&#xff0c;是一种带权路径长度最短的二叉树。所谓树的带权路径长度&#xff0c;就是树中所有的叶结点的权值乘上其到…

为什么要在项目中使用TypeScript?

随着越来越多的开发人员采用TypeScript&#xff0c;人们需要了解在下一个项目中应该使用TypeScript的原因。尽管它在早期应用中遇到了一些阻力&#xff0c;但在过去十年&#xff0c;它迅速成为一种广泛使用的编程语言。 以下介绍如何使用TypeScript以及它给开发人员带来的一些好…