Sql学习第三天——SQL 关于CTE(公用表达式)的递归查询使用

让我来详细讲解一下关于 SQL 中 CTE(公用表达式)的递归查询使用。

什么是 CTE

CTE,全称 Common Table Expression,是用于创建可被其他查询引用的临时结果集的方法,它是一种类似于子查询的结构,但可以被选择、更新、删除或者插入等其他查询复用。

递归查询

递归查询是指在一张表当中进行自我引用的查询操作,用于在具有父子关系的数据中查询某个节点的所有父节点或者所有子节点。

CTE 的递归查询经常应用于树形结构的数据查询,如分类目录、公司组织架构等。

使用 CTE 进行递归查询

CTE 的递归查询需要使用 WITH RECURSIVE 子句进行声明,其基本语法如下:

WITH RECURSIVE [cte_name] ([column1,column2,...]) AS (
  -- non-recursive term
  SELECT [column1,column2,...] FROM [table_name] WHERE [condition]
  UNION ALL
  -- recursive term
  SELECT [column1,column2,...] FROM [table_name] JOIN [cte_name] ON [cte_name].[column_name] = [table_name].[column_name]
  WHERE [condition]
)
SELECT [column1,column2,...] FROM [cte_name];

其中,WITH 子句后的 RECURSIVE 关键字指明了此处使用的是递归查询方式。[cte_name] 表示这个 CTE 的名称,可以取任意合法的标识符。[column1,column2,...] 表示列名称,可以自己指定或从数据表中选取。注意,递归查询必须包含一个非递归查询部分和一个递归查询部分,它们之间的联合是通过 UNION ALL 连接的。

下面通过两个示例来说明 CTE 的递归查询的用法。

示例一

首先,创建一个测试表格employee来表示公司组织架构,它包含三列数据分别是idnamemanager_id

CREATE TABLE employee (
  id INT PRIMARY KEY,
  name varchar(100) NOT NULL,
  manager_id INT
);

INSERT INTO employee (id, name, manager_id) VALUES
(1, 'sam', NULL),
(2, 'mary', 1),
(3, 'jim', 1),
(4, 'andy', 2),
(5, 'bob', 2),
(6, 'lucy', 3),
(7, 'test', 2),
(8, 'mitch', 6);

接下来,使用 CTE 对该表进行递归查询,以查找每一个雇员直接或者间接汇报给的经理。

WITH RECURSIVE emp_list(id, name, manager_id, level) AS (
  -- non-recursive term
  SELECT id, name, manager_id, 0 FROM employee WHERE id = 1
  UNION ALL
  -- recursive term
  SELECT e.id, e.name, e.manager_id, el.level + 1
  FROM employee e
  JOIN emp_list el ON e.id = el.manager_id
)
SELECT id, name, manager_id, level FROM emp_list;

以上 SQL 语句中,第一项非递归查询查询了指定 id 的经理信息,第二项递归查询查找添加到已查询经理列表中的直接下属,通过 JOIN 条件限制条件,一直递归到这个经理没有直接下属为止。

输出结果为:

| id |  name | manager_id | level |
|----|-------|------------|-------|
|  1 |   sam |       NULL |     0 |
|  2 |  mary |          1 |     1 |
|  3 |   jim |          1 |     1 |
|  7 |  test |          2 |     2 |
|  4 |  andy |          2 |     2 |
|  5 |   bob |          2 |     2 |
|  6 |  lucy |          3 |     2 |
|  8 | mitch |          6 |     3 |

输出结果中包括了 id,name 和 manager_id 以及每个雇员距离经理的层数 level,其中经理的 level 为 0。

示例二

接下来,使用 CTE 对一张包含公司部门分类信息的表格department进行递归查询,以查找公司部门的整个分类结构。

CREATE TABLE department (
  id INT PRIMARY KEY,
  name varchar(100) NOT NULL,
  parent_id INT
);

INSERT INTO department (id, name, parent_id) VALUES
(1, 'Animal', NULL),
(2, 'Mammal', 1),
(3, 'Bird', 1),
(4, 'Dog', 2),
(5, 'Cat', 2),
(6, 'Parrot', 3),
(7, 'Pea chicken', 3),
(8, 'Golden retriever', 4);
WITH RECURSIVE department_tree(id, name, parent_id, level) AS (
  SELECT id, name, parent_id, 0 FROM department WHERE id = 1
  UNION ALL
  SELECT dt.id, dt.name, dt.parent_id, dtl.level + 1
  FROM department dt
  JOIN department_tree dtl ON dt.parent_id = dtl.id
)
SELECT id, name, parent_id, level FROM department_tree;

以上 SQL 语句中,第一项非递归查询查询了指定 id 的部门信息,第二项递归查询查找添加到已查询部门列表中的直接上级,通过 JOIN 条件限制条件,一直递归到这个部门没有直接上级为止。

输出结果为:

| id |         name        | parent_id | level |
|----|---------------------|-----------|-------|
|  1 | Animal              |      NULL |     0 |
|  2 | Mammal              |         1 |     1 |
|  5 | Cat                 |         2 |     2 |
|  4 | Dog                 |         2 |     2 |
|  8 | Golden retriever    |         4 |     3 |
|  3 | Bird                |         1 |     1 |
|  6 | Parrot              |         3 |     2 |
|  7 | Pea chicken         |         3 |     2 |

输出结果中包括了 id,name 和 parent_id 以及每个部门距离根节点的层数 level,其中根节点的 level 为 0。

这就是关于 CTE 的递归查询的完整攻略。通过使用 CTE 实现递归查询,可以更加高效地查询具有层级关系的数据,并且在查询效率和查询结果的可读性方面都具有优势。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Sql学习第三天——SQL 关于CTE(公用表达式)的递归查询使用 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • 详解linux后台运行和关闭、查看后台任务

    接下来我将为你详细讲解如何在Linux后台运行和关闭进程,以及如何查看后台任务。下面是完整的攻略,希望可以帮助你更好地理解: Linux后台运行进程 在Linux中,我们使用&符号来让一个命令在后台运行,举个例子,下面的命令会让一个名为”process”的进程在后台运行: $ ./process & 如果想要确保进程在后台运行,即使当前的终端…

    database 2023年5月22日
    00
  • 流程图和数据流图的区别

    下面是我对流程图和数据流图的区别进行详细讲解的攻略。 流程图和数据流图的区别 定义和用途 流程图和数据流图都是软件设计中常用的一种图形化表示方法,用于描述一个系统或程序流程和数据流动的过程。 流程图主要用于描述一个系统或程序中的流程处理过程,从输入到处理再到输出的全过程,同时还可能包括决策、循环等控制结构。它以图形化的形式展示了一个系统或程序的主要业务流程,…

    database 2023年3月27日
    00
  • mysql常用命令大全 mysql常用命令总结

    MySQL常用命令大全 连接命令 连接MySQL服务器 mysql -h [hostname] -u [username] -p -h: 指定MySQL服务器主机名或者IP地址 -u: 指定连接MySQL服务器的用户名 -p: 在输入密码后连接到MySQL服务器 示例:连接到本地MySQL服务器,用户名为root,密码为123456 mysql -h loc…

    database 2023年5月22日
    00
  • Java异常日志堆栈丢失的原因与排查

    Java异常日志堆栈丢失是我们在开发过程中常见的问题之一,也是比较棘手的问题之一。本文将详细讲解Java异常日志堆栈丢失的原因与排查的完整攻略。 什么是Java异常日志堆栈丢失 当Java程序运行时发生异常时,JVM会在控制台或日志文件中打印异常堆栈信息。这些异常堆栈信息是极其重要的,可以帮助我们找到异常的源头并修复问题。然而,在某些情况下,我们可能会发现日…

    database 2023年5月21日
    00
  • mysql 触发器 trigger用法 three (稍微复杂的)

    MySQL包含对触发器的支持。触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。 创建触发器 在MySQL中,创建触发器语法如下: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH RO…

    MySQL 2023年4月13日
    00
  • 解决Redis启动警告问题

    下面为您详细讲解“解决Redis启动警告问题”的完整攻略。 问题描述 在启动 Redis 的过程中,可能会出现警告信息,如下所示: 32455:M 31 May 08:24:16.378 * Increased maximum number of open files to 10032 (it was originally set to 1024). 该警告…

    database 2023年5月22日
    00
  • 整理一下SQLSERVER的排序规则

    整理一下SQLSERVER的排序规则 在SQLSERVER中,排序规则指的是确定如何对文本和字符数据进行排序的规则集。在查询中,通过指定排序规则可以控制查询结果集的顺序,并使排序结果与预期一致。下面就介绍一下SQLSERVER排序规则的相关要点。 排序规则的类型 SQLSERVER中的排序规则主要分为两种类型:“二进制排序规则”和“区分大小写排序规则”。其中…

    database 2023年5月21日
    00
  • Linux下/var/run/目录下的pid文件详解及pid文件作用

    Linux下/var/run/目录下的pid文件详解及pid文件作用 什么是pid文件 pid文件是一种用于记录程序运行时进程ID(PID)的文件,通常保存在/var/run/目录下,也有可能在程序的安装目录下。这个文件通常被用来进行进程的管理和控制。 pid文件的作用 pid文件的作用是记录程序运行时的进程ID,方便在后续的操作中进行对该进程的监控和管理。…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部