【MySQL】MySQL版本8+ 的 with recursive 两种递归语法的使用

力扣题

1、题目地址

1270. 向公司 CEO 汇报工作的所有人

2、模拟表

员工表:Employees

Column NameType
employee_idint
employee_namevarchar
manager_idint
  • employee_id 是这个表具有唯一值的列。
  • 这个表中每一行中,employee_id 表示职工的 ID,employee_name 表示职工的名字,manager_id 表示该职工汇报工作的直线经理。
  • 这个公司 CEO 是 employee_id = 1 的人。

3、要求

编写解决方案,找出所有直接或间接向公司 CEO 汇报工作的职工的 employee_id 。

由于公司规模较小,经理之间的间接关系 不超过 3 个经理 。

可以以 任何顺序 返回无重复项的结果。

返回结果示例如下。

示例 1:

输入:
Employees 表:

employee_idemployee_namemanager_id
1Boss1
3Alice3
2Bob1
4Daniel2
7Luis4
8Jhon3
9Angela8
77Robert1

输出:

employee_id
2
77
4
7

解释:
公司 CEO 的 employee_id 是 1.
employee_id 是 2 和 77 的职员直接汇报给公司 CEO。
employee_id 是 4 的职员间接汇报给公司 CEO 4 --> 2 --> 1 。
employee_id 是 7 的职员间接汇报给公司 CEO 7 --> 4 --> 2 --> 1 。
employee_id 是 3, 8 ,9 的职员不会直接或间接的汇报给公司 CEO。

4、代码编写

我的写法

代码
SELECT employee_id
FROM Employees
WHERE manager_id = 1 AND employee_id != 1
UNION ALL
SELECT employee_id
FROM Employees
WHERE manager_id IN (SELECT employee_idFROM EmployeesWHERE manager_id = 1 AND employee_id != 1
)
UNION ALL
SELECT employee_id
FROM Employees
WHERE manager_id IN (SELECT employee_idFROM EmployeesWHERE manager_id IN (SELECT employee_idFROM EmployeesWHERE manager_id = 1 AND employee_id != 1)
)
代码分析

要求里面有提到:由于公司规模较小,经理之间的间接关系 不超过 3 个经理 ,所以分为三个即可。

直接连接经理:(第一个)

SELECT employee_id
FROM Employees
WHERE manager_id = 1 AND employee_id != 1

间接连接经理:(UNION ALL 连接重复不去重,第二个和第三个)

SELECT employee_id
FROM Employees
WHERE manager_id IN (SELECT employee_idFROM EmployeesWHERE manager_id = 1 AND employee_id != 1
)
UNION ALL
SELECT employee_id
FROM Employees
WHERE manager_id IN (SELECT employee_idFROM EmployeesWHERE manager_id IN (SELECT employee_idFROM EmployeesWHERE manager_id = 1 AND employee_id != 1)
)

网友给出的连表写法(适用于关系层次不深的情景)

代码
SELECT DISTINCT e1.employee_id
FROM Employees e1, Employees e2, Employees e3
WHERE e1.manager_id = e2.employee_id 
AND e2.manager_id = e3.employee_id
AND e3.manager_id = 1 
AND e1.employee_id != 1
代码分析

1、e1.employee_id != 1 这个是排除掉经理(3、2、4、7、8、9、77)
2、e3.manager_id = 1 这个是找出直接连接经理的员工(2,77)
3、e2.manager_id = e3.employee_id 这个是找出直接连接经理的员工的下级员工(2 - 4,77)
4、e1.manager_id = e2.employee_id 这个是找出上面第 3 点下级员工的下级员工(2 - 4 - 7,77)

要从连表去分析太乱了,上面已经是我暂时能理解到的了。
有比较好的理解的小伙伴可以在评论区发表一下自己的见解。

递归写法

with recursive 递归语法知识
1、在 with… as 中声明需要递归的字段

语法:

WITH RECURSIVE 表名 (n) AS
( select 初始值 from tableunion allselect 递归内容 from 表名 where (终止条件)
)
[ SELECT | INSERT | UPDATE | DELETE ]

例子:

WITH RECURSIVE cte (n) AS  
(SELECT 1  # 初始值UNION ALLSELECT n + 1 FROM cte WHERE n < 5  # 递归内容 from cte 表
)
SELECT * FROM cte;

输出结果:

+-----+
|  n  |
+-----+
|  1  |
|  2  |
|  3  |
|  4  |
|  5  |
+-----+

如上所示,可以看出上面 SELECT 1 就代表了输出结果 第一行的数据,也决定了 n 的初始值就是 1,下面 SELECT n + 1 FROM cte WHERE n < 5 是根据上面标注 cte(n)n 为递归字段,重复查询时只要 n < 5 就不断执行 n + 1 操作,当 n = 4 时,n 满足小于 5 的条件,查询出 n + 1 = 5,输出 5n 也变成 5,这时不满足 n < 5 的条件就查询结束了。

2、在 sql 语句中第一段的初始值内声明变量

语法:

WITH recursive 表名 AS ( 初始语句(非递归部分) UNION ALL 递归部分语句
)
[ SELECT | INSERT | UPDATE | DELETE ]

例子:

WITH RECURSIVE cte AS
(SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS strUNION ALLSELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

输出结果:

+-----+--------------+
|  n  | str          |
+-----+--------------+
|  1  | abc          |
|  2  | abcabc       |
|  3  | abcabcabcabc |
+-----+--------------+

如上所示,可以看出 SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS str 代表了输出结果 第一行的数据,也决定了 n 的初始值是 1str 的初始值是 abc,两个都为递归字段,和上面一样,只要满足下面递归语句的条件 n < 3,就累积操作,n + 1 就是 123CONCAT(str, str) 就是 abcabcabcabcabcabcabc

3、参考

SQL:With recursive 递归用法
MySQL8 使用 with recursive 实现递归

代码
WITH RECURSIVE cte AS
(SELECT employee_id FROM Employees a WHERE employee_id != 1 AND manager_id = 1UNION ALLSELECT a.employee_id FROM Employees AS a JOIN cte AS b ON a.manager_id = b.employee_id  
)
SELECT * FROM cte;
代码分析

1、对 employee_id 进行初始化操作,赋予初始值,也为递归字段(查询到直接连接经理的员工)(2,77)

SELECT employee_id 
FROM Employees
WHERE employee_id != 1 AND manager_id = 1

2、开始时上面初始化操作后直接 employee_id 赋值到 b.employee_id,再查询出 a.employee_id 赋值到 employee_id(其实来说 employee_id 就是 b.employee_id,我们可以看到上面 sqlWITH RECURSIVE cte AS 用了 cte,初始值用了 employee_id 作为递归字段,下面递归语句里面 cte 别名为 b,那肯定 b.employee_id 就是 employee_id 了,如果有说错可以标注或评论指出),这里就相当于是查询出直接连接经理员工下面的间接员工(2 - 4,77)(2 - 4 - 7,77)

SELECT a.employee_id 
FROM Employees AS a 
JOIN cte AS b ON a.manager_id = b.employee_id

3、第一次:2,77,第二次:2 - 4,77,第三次:2 - 4 - 7,77

SELECT * FROM cte;

4、会发现确实是 2 和 77 直接连接经理先输出,之后再输出间接连接经理的

| employee_id |
| ----------- |
| 2           |
| 77          |
| 4           |
| 7           |

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

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

相关文章

从0到1实战微服务架构之Nacos下载安装

目录 一、前言 二、Nacos概述 三、Nacos架构 3.1 Open API 3.2 Config Service 3.3 Naming Service 3.4 Nacos Core 3.5 Consistency Protocol 四、Nacos部署实践 4.1 Nacos下载 4.2 Nacos部署 五、总结 一、前言 Nacos是一个开源的、易于使用的、功能丰富的平台&a…

19道ElasticSearch面试题(很全)

点击下载《19道ElasticSearch面试题&#xff08;很全&#xff09;》 1. elasticsearch的一些调优手段 1、设计阶段调优 &#xff08;1&#xff09;根据业务增量需求&#xff0c;采取基于日期模板创建索引&#xff0c;通过 roll over API 滚动索引&#xff1b; &#xff08;…

谓词-量词、主析取、主和取范式、前束范式、推理证明

这部分内容&#xff0c;主要需要掌握谓词推理&#xff0c;而前提是掌握将自然语言符号化为谓词、用量词来限定辖域&#xff0c;量词的消去、剩下就是推理过程。还需要掌握的是主析取、主和取范式和前束范式。 存在量词∃&#xff1a;至少有一个 全称量词∀&#xff1a;全都是…

Linux驱动学习—输入子系统

1、什么是输入子系统&#xff1f; 输入子系统是Linux专门做的一套框架来处理输入事件的&#xff0c;像鼠标&#xff0c;键盘&#xff0c;触摸屏这些都是输入设备&#xff0c;但是这邪恶输入设备的类型又都不是一样的&#xff0c;所以为了统一这些输入设备驱动标准应运而生的。…

GB/T 15036-2018 实木地板检测

实木地板是指未经拼接、覆贴的单块木材直接加工而成的地板&#xff0c;实木地板具有脚感舒适&#xff0c;环保等优良的性能&#xff0c;在家庭装修中被广泛使用&#xff0c;尤其是在国内很受欢迎。 GB/T 15036-2018 实木地板测试介绍&#xff1a; 测试项目 测试方法 外观 G…

50天精通Golang(第13天)

反射reflect 一、引入 先看官方Doc中Rob Pike给出的关于反射的定义&#xff1a; Reflection in computing is the ability of a program to examine its own structure, particularly through types; it’s a form of metaprogramming. It’s also a great source of confus…

代码随想录算法训练营第60天|● 84.柱状图中最大的矩形

84. 柱状图中最大的矩形 困难 相关标签 相关企业 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: [图片] 输入&#xff1a;heights [2,1,5,6…

springCould中的Bus-从小白开始【11】

目录 &#x1f9c2;1.Bus是什么❤️❤️❤️ &#x1f32d;2.什么是总线❤️❤️❤️ &#x1f953;3.rabbitmq❤️❤️❤️ &#x1f95e;4.新建模块3366❤️❤️❤️ &#x1f373;5.设计思想 ❤️❤️❤️ &#x1f37f;6.添加消息总线的支持❤️❤️❤️ &#x1f9…

世邦IP网络对讲广播系统 uploadjson.php接口处存在任意文件上传漏洞

产品简介 SPON世邦IP网络对讲广播系统是一种先进的通信解决方案&#xff0c;旨在提供高效的网络对讲和广播功能。 漏洞概述 SPON世邦IP网络对讲广播系统 uploadjson.php接口处存在任意文件上传漏洞&#xff0c;未经身份验证的攻击者可利用此漏洞上传恶意后门文件&#xff0c…

【UE Niagara学习笔记】05 - 喷射火焰顶部的蓝色火焰

在上一篇博客&#xff08;【UE Niagara学习笔记】04 - 火焰喷射时的黑烟效果&#xff09;的基础上继续实现在火焰喷射的起点位置生成蓝色火焰的效果。 目录 效果 步骤 1. 创建新的发射器 2. 减少粒子生成数量 3. 减小粒子初始大小 4. 减少粒子喷射距离 5. 减少粒子初始…

Java基础- Function接口

我们来看一个 Function 接口的例子。假设我们有一个任务&#xff0c;需要处理一个员工对象列表&#xff0c;将每个员工的信息格式化为字符串&#xff0c;同时根据一些规则&#xff08;如年龄、工作年限等&#xff09;来过滤员工。这个任务可以通过使用 Function 接口以及流&…

Jenkins持续集成

1. Jenkins插件 Jenkins做持续集成很好用&#xff0c;这里只是为了列一下我们经常使用的插件。目前加的比较少&#xff0c;以后可以逐步完善。 必备插件&#xff1a; 1. Credentials Plugin授权插件&#xff0c;不解释。 2. Matrix Authorization Strategy Plugin 矩阵式授权…

前端(angular)在谷歌(chrome)浏览器使用高德地图api定位报错超时geolocation time out ,能定位但不安全的方法

已知信息整合 正如大家搜到的大佬说的原因是chrome浏览器本身的问题。我换成edge就可以。高德地图给出的地图定位api的常见问题&#xff0c;这是另外还有个别浏览器&#xff08;如google Chrome浏览器等&#xff09;本身的定位接口是黑洞 以下是能定位但不安全的方法 连接上…

网络协议攻击与模拟_02ARP协议

一、arp协议简介 一个工作在二层的三层协议&#xff0c;事一个2.5层协议 ARP协议地址解析协议&#xff0c;将一个已知的Ip地址解析为MAC地址&#xff0c;从而进行二层数据交互 二、工作流程 1、两个阶段 ARP请求ARP响应 两台主机IP地址主机A和主机B&#xff0c;IP地址和MAC…

固乔快递查询助手:一键批量查询,省时省力

在快递行业飞速发展的今天&#xff0c;高效、准确地掌握快递信息对于电商卖家、物流公司管理者以及经常需要查询快递信息的消费者来说至关重要。固乔快递查询助手正是为此而生&#xff0c;它的批量查询功能为用户带来前所未有的便利和高效。 首先&#xff0c;如何下载固乔快递查…

深入理解 Flink(四)Flink Time+WaterMark+Window 深入分析

Flink Window 常见需求背景 需求描述 每隔 5 秒&#xff0c;计算最近 10 秒单词出现的次数 —— 滑动窗口 每隔 5 秒&#xff0c;计算最近 5 秒单词出现的次数 —— 滚动窗口 关于 Flink time 种类 TimeCharacteristic ProcessingTimeIngestionTimeEventTime WindowAssign…

kube-state-metrics组件

kube-state-metrics&#xff1a;kube-state-metrics 通过监听 API Server 生成有关资源对象的状态指标&#xff0c;比如 Deployment、Node、Pod&#xff0c;需要注意的是 kube-state-metrics 只是简单提供一个 metrics 数据&#xff0c;并不会存储这些指标数据&#xff0c;所以…

解析c++空指针解引用奔溃

空指针解引用引起程序奔溃是c/c中最常见的稳定性错误之一。 显然并非所有使用空指针的语句都会导致奔溃&#xff0c;那什么情况下使用空指针才会引起程序奔溃呢&#xff1f;有一个判断标准&#xff1a;判断空指针是否会导致访问非法内存的情况&#xff0c;如果会导致访问非法内…

大模型LLM在 Text2SQL 上的应用实践

一、前言 目前&#xff0c;大模型的一个热门应用方向Text2SQL&#xff0c;它可以帮助用户快速生成想要查询的SQL语句&#xff0c;再结合可视化技术可以降低使用数据的门槛&#xff0c;更便捷的支持决策。本文将从以下四个方面介绍LLM在Text2SQL应用上的基础实践。 Text2SQL概…

Crow:蓝图路由1 CROW_BP_ROUTE

蓝图路由简单点说可以认为先给路由设置一个根目录,然后在该根目录下设置子路由,比如: 设置蓝图路由为/user/,然后添加子路由add, delete,那么总的路由相当于: /user/add和/user/delete 看一下Crow的实现: #define CROW_ROUTE(app, url) app.template route<crow::…