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

yizhihongxing

让我来详细讲解一下关于 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日

相关文章

  • 浅谈MySQL的B树索引与索引优化小结

    我们来详细讲解一下“浅谈MySQL的B树索引与索引优化小结”的攻略。 浅谈MySQL的B树索引与索引优化小结 什么是B树索引? B树是一种多路平衡搜索树,常被用来实现关系型数据库中的索引。B树不同于二叉树,一个B树节点可以包含许多数据项以及指向其他节点的指针,被称为“分支节点”。B树一般用于磁盘存储系统中,可以有效减少磁盘I/O读取次数,提高数据的访问速度。…

    database 2023年5月19日
    00
  • postgreSQL数据库基本概念教程

    PostgreSQL数据库基本概念教程 PostgreSQL是一种高度可扩展的开源关系型数据库管理系统。它有着广泛的使用领域,包括web应用、大数据、金融、人力资源、物流等等。本教程将介绍PostgreSQL数据库的基本概念。 数据类型 PostgreSQL支持多种数据类型,包括整数、浮点数、字符串、日期、数组、JSON等等。以下是一些常用数据类型的示例: …

    database 2023年5月21日
    00
  • MySQL复合索引的深入探究

    MySQL复合索引的深入探究 MySQL中复合索引(也称多列索引)是指包含多个列的索引。与单列索引相比,复合索引可以有效地优化查询效率。但是,复合索引也有一些需要注意的细节。在本文中,我们将深入探究MySQL中复合索引的优化技巧以及使用时需要注意的细节。 复合索引的使用 在使用复合索引时,首先需要明确复合索引的定义。复合索引的定义是基于列上的多个索引,可以在…

    database 2023年5月22日
    00
  • MySQL5.7更改密码时出现ERROR 1054 (42S22)的解决方法

    当我们在MySQL5.7版本下更改密码时,有时会遇到ERROR 1054 (42S22)的情况。如果出现这种错误,我们需要采取以下步骤进行解决: 问题背景: 在MySQL5.7版本下更改密码时,会执行下列语句: mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘new_password’; 但是在执…

    database 2023年5月18日
    00
  • redis内存溢出问题分析和后续规避方法

    【bug描述】 【步骤】 1、【前置:当前时间是2018年2月6日】用户A登录客户端A,用户A登录客户端B,查看客户端账号被踢出登录时的弹窗时间显示8月24日,时间显示错误。2、【前置:该弹窗提示平台已经屏蔽】消息列表点击任意群聊,进入群聊对话窗提示:“XX项目升级,部分功能暂停使用,敬请谅解”。 【实际结果】:1、【前置:当前时间是2018年2月6日】账号…

    Redis 2023年4月13日
    00
  • 20道Redis面试题,面试官能问的都被我找到了(含答案)

    20道Redis面试题攻略 1. Redis的数据类型 Redis支持多种数据类型,包括字符串(string)、哈希(hash)、列表(list)、集合(set)和有序集合(sorted set)。其中: 字符串是最基本的数据类型,可以存储任意类型的数据,包括二进制数据。字符串类型有一个最大值限制,最大长度为512MB. 哈希类型是一个键值对集合,可以存储多…

    database 2023年5月22日
    00
  • DBMS中分类和聚类的区别

    DBMS中分类(classification)和聚类(clustering)是两个非常常见的数据挖掘(data mining)技术,主要应用于无监督学习(unsupervised learning)场景中。虽然这两者在表面上看起来非常相似,但它们在实现方法和应用场景上存在一些区别。 分类(classification) 分类是一种基于预先定义好的类别(cat…

    database 2023年3月27日
    00
  • 最全mysql数据类型梳理汇总

    最全MySQL数据类型梳理汇总 MySQL是目前最流行的关系型数据库之一,MySQL支持的数据类型非常丰富,本篇攻略将从以下几个方面详细讲解MySQL的数据类型: 数据类型分类 整数类型 小数类型 日期和时间类型 字符串类型 二进制数据类型 枚举类型和集合类型 在本篇攻略中,我们将对每一种数据类型进行详细的讲解并提供示例说明,以帮助读者更好地了解MySQL的…

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