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中修改tomcat端口号

    在Linux中修改tomcat的端口号有以下步骤: 登录到Linux服务器首先需要登录到Linux服务器,可以使用SSH等方式进行登录。 停止Tomcat服务修改Tomcat配置文件需要先关闭Tomcat服务,可以使用以下命令停止Tomcat: sudo systemctl stop tomcat 打开server.xml文件 Tomcat的端口号配置保存在…

    database 2023年5月22日
    00
  • mysql——索引的添加删除及排序

    今天一顿操作,猛如虎,把一个部署到2核4g的小服务器挂掉了。 幡然醒悟,关联操作还是要加上索引比较好,运行速度从几分钟迅速提到几秒。   1.mysql添加索引的方法主要有以下几种(可以对关联的字段提前建索引,然后再关联)。 a.添加PRIMARY KEY(主键索引) mysql>ALTER TABLE `table_name` ADD PRIMARY…

    MySQL 2023年4月13日
    00
  • MySQL索引最左匹配原则实例详解

    MySQL索引最左匹配原则是指当我们使用多列索引进行查询时,只有索引的最左边的列才能被用于索引扫描,即只有最左前缀匹配的列会被索引扫描,这是MySQL查询优化的一个重要原则。 具体来说,当使用多列索引进行查询时,MySQL只会使用最左边的列作为索引键进行查找,找到符合条件的最左前缀匹配的行,并返回这些行的主键值;然后在这些行中再进行二次查找,即对最左前缀匹配…

    database 2023年5月22日
    00
  • 浅谈JDK14性能管理工具之jmap和jhat

    浅谈JDK14性能管理工具之jmap和jhat 什么是jmap和jhat jmap和jhat是JDK自带的性能管理工具,用于诊断和分析Java应用程序的内存使用情况。 jmap能够生成Java堆转储快照,可以获取Java堆中各种对象的详细信息。 jhat能够解析jmap生成的堆转储文件,将其中的数据展示为易于理解的HTML格式,方便开发者分析和调试。 jma…

    database 2023年5月21日
    00
  • centOS安装mysql5.7详细教程

    CentOS安装MySQL 5.7详细教程 本教程介绍CentOS系统下安装MySQL 5.7的详细步骤。 环境准备 在开始安装过程前,请确保你的CentOS系统已经安装了epel-release仓库和wget工具,如果没有,请先执行以下命令进行安装: sudo yum -y install epel-release wget 下载MySQL RPM包 访问…

    database 2023年5月22日
    00
  • PHP mysql事务问题实例分析

    PHP mysql事务问题实例分析 什么是事务 数据库事务是指批量操作中的所有单个操作作为整体的执行过程。事务可以被视为某个进程或线程执行的所有数据库操作的逻辑集合,这些操作被视为一个单独的工作单元,这些操作要么全部完成,要么全部不执行。 在PHP mysql事务中,要使用Begin、Rollback和Commit三个命令来控制事务的结果。 事务的关键点 B…

    database 2023年5月21日
    00
  • 在 Ubuntu 16.04 为 Nginx 服务器安装 LEMP 环境(MariaDB,PHP 7 并支持 HTTP 2.0)

    下面我将为您详细讲解“在 Ubuntu 16.04 为 Nginx 服务器安装 LEMP 环境(MariaDB,PHP 7 并支持 HTTP 2.0)”的完整攻略。 环境要求 在开始设置 LEMP 环境之前,请确保已满足以下条件: 已使用 sudo 权限登录到 Ubuntu 16.04 服务器; 已安装 Nginx 服务器; 已配置域名解析到服务器的 IP …

    database 2023年5月22日
    00
  • 单用户和多用户数据库系统的区别

    单用户数据库系统和多用户数据库系统都是常见的数据库系统,主要区别在于能够同时访问数据库的用户数量。以下是单用户和多用户数据库系统的详细讲解,包括各自的特点、优缺点和示例说明。 单用户数据库系统 单用户数据库系统指只能由单个用户进行操作,不能同时由多个用户进行访问和使用。这种数据库系统通常只限于个人使用或小型组织使用,例如小型企业、学校或家庭用户。 特点 只能…

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