迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 数据库 > MySQL >

MySQL 递归查询

作者:迹忆客 最近更新:2023/04/18 浏览次数:

在本指南中,我们将了解 MySQL 的递归查询。 如何在 SQL 中编写递归查询及其工作原理将在本指南中进行解释,以便您更好地理解。


MySQL 递归查询

SQL中的递归查询是子查询; 顾名思义,它以递归方式工作。 它有一个基本案例、一个用户定义的名称和一个带有终止条件的递归案例。

with [Recursive] CTE(user_defined name) AS
(
    SELECT query (Non Recursive query or the Base query)
    UNION
    SELECT query (recursive query using the name [with a termination condition])
)
SELECT * from CTE_name;

以上是递归SQL查询的伪代码。 让我们更深入地研究它。

with 从句

with [Recursive] CTE(user_defined name) AS

SQL 的with 子句在开头使用,与SQL 的Recursive 关键字一起使用。 然后使用 AS 关键字,后跟 CTE,一个用户定义的名称。

这种关键字语法构成了我们查询的基本情况。

CTE 称为公用表表达式,是用户定义的临时命名结果集,稍后在后续的 SELECT 语句中使用。

基本查询

SELECT query (Non Recursive query or the Base query)

这是称为基本查询的两个查询中的第一个。 这是一个非递归查询,这里将根据递归发生的基础输入提供基本输入。

UNION 语句

UNION

中间使用 Union 运算符合并我们的第一个和第二个查询。

递归查询

SELECT query (recursive query using the name [with a termination condition])

这是递归查询,我们需要提供之前使用 with 子句创建的 CTE 表,并提供终止条件,当它变为真时,将终止递归。

Base和Recursive query写在括号()里面,如上面的伪代码所示。

SELECT * from CTE_name

此查询将查看使用此递归技术创建的表。


在 MySQL 中实现递归查询

让我们通过正确地实现这个查询来理解它的工作原理。

with recursive number_printer AS
(
    SELECT 1 AS digit
    UNION
    SELECT digit+1 FROM number_printer WHERE digit<5
)
SELECT * FROM number_printer

number printer

上表是我们程序执行的结果。 这是它的执行方式。

查询开始使用 with 子句和递归关键字,我们使用 print_number 作为我们的 CTE。 一旦我们执行代码,程序就会寻找一个基本案例,因为它知道这是一个递归查询。

在base query中,我们从1开始base case,这里使用的别名是digit。 在执行的第一次迭代中,输出将是从基本查询返回的结果。

初始记录将是基本查询的输出。

从基本查询返回的结果将成为递归查询的输入。 在第二次迭代中,递归查询使用前一个查询的输出数据并检查终止条件。

如果满足终止条件,则迭代停止; 否则进入第三次迭代。 第三次迭代使用第二次迭代返回的输出作为输入。

这是递归发生的唯一逻辑。

执行第三次迭代,并将此迭代的结果输出用作第四次迭代的输入。 第四次迭代然后将基本查询的输出与其输入相加。

它一直递归发生,直到满足终止条件。

该表,即 number_printer,在这里非常重要。 必须使用该表来使此查询递归。 对于查询的完成,使用 WHERE 子句编写终止条件。

现在,让我们再举一个关于递归查询的例子。

示例 2:层次结构

假设我们有一个具有某种层次结构的组织。 最高层有一名经理,两名经理受该经理的直接监督,而这两名经理中的每一位都有一名直接受其监督的经理。

现在,我们已经创建了一个名为 network 的表,其中包含 id、name 和 ManagerID 等列。 它们分别定义了员工的 ID、姓名和经理 ID。

如下表所示:

network

在上表中,我们获得了员工的姓名和经理 ID,但我们希望根据我们之前讨论的层次结构为这些经理正确分配等级。 因此,我们使用以下代码:

WITH RECURSIVE hierarchy AS
( SELECT id, name, 1 AS level FROM network WHERE id = 1
UNION
SELECT n.id, n.name, h.level+1 FROM hierarchy h
JOIN network n on h.id = n.ManagerID
)
SELECT * FROM hierarchy

上面的递归查询代码将如我们所愿地解决问题。 让我们深入了解这段代码的作用。

With 子句根据语法与 Recursive 关键字一起使用,这里的 CTE 命名为层次结构。

在基本查询中,它从网络表中选择 id 和 name,并获取 id 等于 1 的值。然后,它将其值 AS level 设置为整数 1。

此处使用级别来展示经理在层次结构中的位置。

我们完成了基本查询; 现在,代码使用 UNION 子句将基本查询与递归查询合并。

递归查询从网络表中选择 id 和 name。 这里的 n 是网络表的别名,这个点 (.) 在这里的作用是限制要从我们在它之前作为输入提供的特定表中获取的值。

h 是层次表的别名,子句 level+1 确保从层次表中获取的整数值加 1。

这部分递归查询从network表中取name和id,整数值来自hierarchy,对其进行加1,输出保存在level中。 此查询更新并定义经理的级别。

在查询的下一部分中,使用了 JOIN 子句,默认情况下它作为内部连接运行。 在这里,网络表中的 ManagerID 与层次结构表中的 ID 相匹配,并与上述查询进行内部连接。

逻辑是,当经理 ID 与 ID 匹配时,通过将经理的级别加 1 来分配该实体的级别。 这样,监督的排名就分配好了。

hierarchy

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

使用 Mysqldump 备份 MySQL 中的数据

发布时间:2023/05/09 浏览次数:192 分类:MySQL

本篇文章将介绍如何使用 mysqldump 只备份数据。 在这里,我们将探讨 --no-create-info 、--compact 、--skip-triggers 和 --no-create-db 选项。

更新 MySQL 表中的主键

发布时间:2023/05/09 浏览次数:61 分类:MySQL

本篇文章介绍如何更新 MySQL 表中的主键。 我们将使用 ALTER 命令对主键进行任何更改。更新 MySQL 表中的主键 我们可以在多种情况下更新 MySQL 表中的主键。

在 MySQL 中获取命令历史记录

发布时间:2023/05/09 浏览次数:150 分类:MySQL

本文重点介绍了在 Windows 和 Linux 中获取我们已执行的 MySQL 命令历史记录的各种方法。MySQL命令历史

Oracle 的 decode 函数在 MySQL 中的等价物

发布时间:2023/05/09 浏览次数:115 分类:MySQL

本篇文章介绍了三种替代实现,我们可以将它们用作 MySQL 中 Oracle 的 decode() 函数的等价物。 为此,我们将使用 IF()、CASE 以及 FIELD() 和 ELT() 的组合。

在 Linux 中安装 MySQL 客户端

发布时间:2023/05/09 浏览次数:72 分类:MySQL

在 Linux 中安装 MySQL 客户端的命令。Linux 和 Unix 等环境作为命令行界面工作,仅在命令的帮助下运行。

在 MySQL 中转换为十进制

发布时间:2023/05/09 浏览次数:150 分类:MySQL

有时,我们可能需要将一种数据类型转换为另一种数据类型。 下面是我们如何使用带有 DECIMAL(M,D) 的 CAST() 和 CONVERT() 函数在 MySQL 中转换为十进制。

在 MySQL 中获取当前日期和时间

发布时间:2023/05/09 浏览次数:145 分类:MySQL

本篇文章我们将学习 NOW()、CURRENT_TIMESTAMP()(也写为 CURRENT_TIMESTAMP)和 SYSDATE() 来获取 MySQL 中的当前日期和时间。 我们还将看到这三个功能之间的比较。在 MySQL 中获取当前日期和时间

更改 MySQL 服务器中的 max_allowed_packet Size

发布时间:2023/05/09 浏览次数:142 分类:MySQL

本篇文章介绍如何更改 MySQL 服务器中的 max_allowed_packet 大小。 为了了解这一点,我们将使用两个操作系统,Windows 10 和 Linux (Ubuntu)。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便