MySQL 入门教程
  • 教程目录
  • 第一章 基础教程
    • 第一节 入门
      • 1.1 安装
      • 1.2 示例数据库
    • 第二节 查询数据
      • 2.1 SELECT 语句
      • 2.2 SELECT DISTINCT 语句
    • 第三节 过滤数据
      • 3.1 WHERE 子句
      • 3.2 AND 运算符
      • 3.3 OR 运算符
      • 3.4 IN 运算符
      • 3.5 BETWEEN 运算符
      • 3.6 LIKE 运算符
      • 3.7 LIMIT 子句
      • 3.8 IS NULL 运算符
    • 第四节 数据排序
      • 4.1 ORDER BY 子句
      • 4.1 自然排序
    • 第五节 连接表
      • 5.1 别名
      • 5.2 INNER JOIN
      • 5.3 LEFT JOIN
      • 5.4 自连接
      • 5.5 CROSS JOIN
    • 第六节 分组数据
      • 6.1 GROUP BY子句
      • 6.2 HAVING 子句
    • 第七节 子查询,派生表和通用表达式
      • 7.1 子查询
      • 7.2 派生表
      • 7.3 公共表表达式
      • 7.4 递归 CTE
    • 第八节 集合操作符
      • 8.1 UNION 和 UNION ALL
      • 8.2 INTERSECT 模拟
    • 第九节 修改数据
      • 9.1 INSERT 语句
      • 9.2 INSERT IGNORE
      • 9.3 UPDATE 语句
      • 9.4 UPDATE JOIN 语句
      • 9.5 DELETE
      • 9.6 ON DELETE CASCADE.
      • 9.7 DELETE JOIN
      • 9.8 REPLACE 语句
      • 9.9 PREPARE 语句
    • 第十节 事务
      • 10.1 事务介绍
      • 10.2 表锁定
    • 第十一节 管理数据库和表
      • 11.1 数据库管理
      • 11.2 MySQL 表类型
      • 11.3 CREATE TABLE
      • 11.4 序列
      • 11.5 ALTER TABLE
      • 11.6 重命名表
      • 11.7 从表中删除列
      • 11.8 向表中添加新列
      • 11.9 删除表
      • 11.10 临时表
      • 11.11 TRUNCATE TABLE
    • 第十二节 索引
      • 12.1 管理索引
      • 12.1 UNIQUE 索引
    • 第十三节 数据类型
      • 13.1 INT
      • 13.2 DECIMAL
      • 13.3 BIT
      • 13.4 BOOLEAN
      • 13.5 CHAR
      • 13.6 VARCHAR
      • 13.7 TEXT
      • 13.8 DATE
      • 13.9 TIME
      • 13.10 DATETIME
      • 13.11 TIMESTAMP
      • 13.12 JSON
      • 13.13 ENUM
    • 第十四节 约束
      • 14.1 NOT NULL 约束
      • 14.2 主键约束
      • 14.2 外键约束
      • 14.4 UNIQUE 约束
      • 14.5 CHECK 约束
    • 第十五节 全球化
      • 15.1 字符集
      • 15.2 校对规则
    • 第十六节 导入和导出
      • 16.1 导入 CSV 文件
      • 16.2 导出为 CSV
  • 第二章 技巧
    • CTE 简介
    • 递归 CTE
    • 邻接列表模型和层次结构
    • 获取行数
    • 比较表
    • 找重复值
    • 删除重复行
    • UUID 和主键
    • 复制表数据
    • 变量
    • 生成列
    • 连续行比较
    • 更改存储引擎
    • 基于正则表达式的搜索
    • row_number 模拟
    • 随机选择记录
    • 选择第 n 个最高纪录
    • 重置自动增量值
    • MariaDB 与 MySQL 比较
    • 间隔
    • NULL 详细和应用
    • 获取今天的日期
    • 将NULL值映射到有意义的值
    • 注释
  • 第三章 存储过程
    • 简介
    • 入门
    • 变量
    • 参数
    • 返回多个值
    • IF语句
    • CASE语句
    • IF和CASE语句的技巧
    • 循环
    • 游标
    • 列出存储过程
    • 错误处理
    • SIGNAL 和 ESIGNAL 语句
    • 存储函数
  • 第四章 触发器
    • 实现
    • 创建
    • 创建多个触发器
    • 管理
    • 计划事件
    • 修改事件
  • 第五章 视图
    • 简介
    • 实现和限制
    • 创建
    • 可更新视图
    • 确保视图一致性
    • 检查选项子句
    • 管理
  • 第六章 全文搜索
    • 简介
    • 定义索引
    • 自然语言全文搜索
    • 布尔全文搜索
    • 查询扩展
    • ngram全文解析器
  • 第七章 函数
  • 第八章 管理
    • 访问控制系统入门
    • 创建用户
    • 授予权限
    • 撤销权限
    • 角色管理
    • 删除用户
    • 维护数据库表
    • 备份数据库
    • 列出数据库
    • 列出表
    • 列出表的列
    • 列出用户
Powered by GitBook
On this page
  • 1. 什么是公用表表达式或CTE?
  • 2. MySQL CTE语法
  • 3. 简单的MySQL CTE示例
  • 4. 更高级的MySQL CTE示例
  • 5. WITH子句用法

Was this helpful?

  1. 第一章 基础教程
  2. 第七节 子查询,派生表和通用表达式

7.3 公共表表达式

Previous7.2 派生表Next7.4 递归 CTE

Last updated 5 years ago

Was this helpful?

在本教程中,您将学习如何使用MySQL CTE或公用表表达式以更可读的方式构建复杂查询。

自MySQL 8.0版以来简要介绍了公共表表达式或叫CTE的功能,因此需要您在计算机上安装MySQL 8.0,以便在本教程中练习本语句。

1. 什么是公用表表达式或CTE?

公用表表达式是一个命名的临时结果集,仅在单个SQL语句(例如,,或)的执行范围内存在。

与类似,CTE不作为对象存储,仅在查询执行期间持续。 与派生表不同,CTE可以是自引用(),也可以在同一查询中多次引用。 此外,与派生表相比,CTE提供了更好的可读性和性能。

2. MySQL CTE语法

CTE的结构包括名称,可选列列表和定义CTE的查询。 定义CTE后,可以像SELECT,INSERT,UPDATE,DELETE或CREATE VIEW语句中的视图一样使用它。

以下说明了CTE的基本语法:

WITH cte_name (column_list) AS (
    query
) 
SELECT * FROM cte_name;

请注意,查询中的列数必须与column_list中的列数相同。 如果省略column_list,CTE将使用定义CTE的查询的列列表。

3. 简单的MySQL CTE示例

以下示例说明如何使用CTE查询中的customers表中的数据。 请注意,此示例仅用于演示目的,以便您更容易地了解CTE概念。

WITH customers_in_usa AS (
    SELECT 
        customerName, state
    FROM
        customers
    WHERE
        country = 'USA'
) SELECT 
    customerName
 FROM
    customers_in_usa
 WHERE
    state = 'CA'
 ORDER BY customerName;

注意:上面语句只能在 MySQL8.0 以上版本才支持。

执行上面查询语句,得到以下结果(部分)

在此示例中,CTE的名称为customers_in_usa,定义CTE的查询返回两列:customerName和state。因此,customers_in_usa CTE返回位于美国的所有客户。

在定义美国CTE的客户之后,我们可在SELECT语句中引用它,例如,仅查询选择位于California 的客户。

参见另外一个例子:

WITH topsales2013 AS (
    SELECT 
        salesRepEmployeeNumber employeeNumber,
        SUM(quantityOrdered * priceEach) sales
    FROM
        orders
            INNER JOIN
        orderdetails USING (orderNumber)
            INNER JOIN
        customers USING (customerNumber)
    WHERE
        YEAR(shippedDate) = 2013
            AND status = 'Shipped'
    GROUP BY salesRepEmployeeNumber
    ORDER BY sales DESC
    LIMIT 5
)
SELECT 
    employeeNumber, firstName, lastName, sales
FROM
    employees
        JOIN
    topsales2013 USING (employeeNumber);

执行上面查询后,得到以下结果 -

在这个例子中,CTE中返回了在2013年前五名的销售代表。之后,我们引用了topsales2013 CTE来获取有关销售代表的其他信息,包括名字和姓氏。

4. 更高级的MySQL CTE示例

请参阅以下示例:

WITH salesrep AS (
    SELECT 
        employeeNumber,
        CONCAT(firstName, ' ', lastName) AS salesrepName
    FROM
        employees
    WHERE
        jobTitle = 'Sales Rep'
),
customer_salesrep AS (
    SELECT 
        customerName, salesrepName
    FROM
        customers
            INNER JOIN
        salesrep ON employeeNumber = salesrepEmployeeNumber
)
SELECT 
    *
FROM
    customer_salesrep
ORDER BY customerName;

执行上面查询语句,得到以下结果 -

在这个例子中,在同一查询中有两个CTE。 第一个CTE(salesrep)获得职位是销售代表的员工。 第二个CTE(customer_salesrep)使用INNER JOIN子句与第一个CTE连接来获取每个销售代表负责的客户。

5. WITH子句用法

有一些上下文可以使用WITH子句来创建公用表表达式(CTE):

首先,在SELECT,UPDATE和DELETE语句的开头可以使用WITH子句:

WITH ... SELECT ...
WITH ... UPDATE ...
WITH ... DELETE ...

第二,可以在子查询或派生表子查询的开头使用WITH子句:

SELECT ... WHERE id IN (WITH ... SELECT ...);

SELECT * FROM (WITH ... SELECT ...) AS derived_table;

第三,可以在SELECT语句之前立即使用WITH子句,包括SELECT子句:

CREATE TABLE ... WITH ... SELECT ...
CREATE VIEW ... WITH ... SELECT ...
INSERT ... WITH ... SELECT ...
REPLACE ... WITH ... SELECT ...
DECLARE CURSOR ... WITH ... SELECT ...
EXPLAIN ... WITH ... SELECT ...

在本教程中,您已经学会了如何使用MySQL 公共表表达式(CTE)来构造复杂的查询语句。

在使用第二个CTE之后,使用带有子句的简单SELECT语句来查询来自该CTE的数据。

SELECT
INSERT
UPDATE
DELETE
派生表
递归CTE
示例数据库(yiibaidb)
ORDER BY
img
img
img