在 MySQL 中使用 CTE

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 【8月更文挑战第11天】

在 MySQL 中,公共表表达式(Common Table Expression,简称 CTE)是一种强大的查询工具,尤其在处理复杂查询时非常有用。CTE 提供了将复杂查询分解为多个易于管理的部分的能力,提高了查询的可读性和组织性。本文将详细介绍如何在 MySQL 中使用 CTE,包括其基本语法、使用方法、示例以及注意事项。

1. CTE 的基本概念

1.1 什么是 CTE?

CTE 是在 SQL 查询中定义的一个临时结果集,其作用范围仅限于定义它的查询。CTE 通常用于简化复杂查询,并可以用于递归查询。CTE 的定义部分类似于创建一个临时视图,但其生命周期仅限于当前查询。

2. CTE 的基本语法

在 MySQL 中,CTE 的基本语法如下:

WITH cte_name AS (
    SELECT column1, column2, ...
    FROM table_name
    WHERE conditions
)
SELECT column1, column2, ...
FROM cte_name
WHERE conditions;
  • WITH cte_name AS (...):定义一个名为 cte_name 的 CTE,其中包含一个查询语句。
  • SELECT column1, column2, ... FROM cte_name WHERE conditions:使用 CTE 的结果进行进一步的查询。

3. 示例操作

3.1 基本示例

假设我们有一个 employees 表,包含员工的信息。我们希望从表中获取所有工资高于 50000 的员工,并且这些员工的部门名称是“销售部”。

创建表的示例:

CREATE TABLE employees (
    employee_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    salary DECIMAL(10, 2),
    department VARCHAR(100)
);

INSERT INTO employees (name, salary, department) VALUES
('Alice', 55000, 'Sales'),
('Bob', 48000, 'Marketing'),
('Charlie', 60000, 'Sales'),
('David', 45000, 'HR');

使用 CTE 获取工资高于 50000 的员工:

WITH high_salary_employees AS (
    SELECT employee_id, name, salary, department
    FROM employees
    WHERE salary > 50000
)
SELECT name, salary
FROM high_salary_employees
WHERE department = 'Sales';

结果:

name    | salary
--------+--------
Alice   | 55000
Charlie | 60000

在这个示例中,high_salary_employees 是一个 CTE,它包含了工资高于 50000 的员工。接下来的查询从 CTE 中筛选出部门为“销售部”的员工。

3.2 使用 CTE 进行递归查询

CTE 支持递归查询,这对于处理层次结构数据(如组织结构图)非常有用。递归 CTE 包括两个部分:基础查询和递归查询。

示例:

假设我们有一个 employees 表,记录了员工的管理层级。我们希望找出某位员工的所有下属。

创建表的示例:

CREATE TABLE employees (
    employee_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    manager_id INT
);

INSERT INTO employees (name, manager_id) VALUES
('CEO', NULL),
('Manager1', 1),
('Manager2', 1),
('Employee1', 2),
('Employee2', 2),
('Employee3', 3);

使用递归 CTE 查找某位员工的下属:

WITH RECURSIVE subordinates AS (
    SELECT employee_id, name, manager_id
    FROM employees
    WHERE name = 'CEO'

    UNION ALL

    SELECT e.employee_id, e.name, e.manager_id
    FROM employees e
    INNER JOIN subordinates s ON e.manager_id = s.employee_id
)
SELECT name
FROM subordinates;

结果:

name
---------
CEO
Manager1
Manager2
Employee1
Employee2
Employee3

在这个示例中,subordinates CTE 递归地查找“CEO”下的所有员工,包括直接和间接下属。

4. CTE 的应用场景

4.1 数据汇总和分析

CTE 可以用于复杂的数据汇总和分析,简化查询逻辑。通过将查询分解为多个 CTE,可以逐步处理数据,逐步构建最终结果。

示例:

WITH sales_data AS (
    SELECT salesperson, SUM(sales_amount) AS total_sales
    FROM sales
    GROUP BY salesperson
),
ranked_sales AS (
    SELECT salesperson, total_sales,
           RANK() OVER (ORDER BY total_sales DESC) AS sales_rank
    FROM sales_data
)
SELECT salesperson, total_sales, sales_rank
FROM ranked_sales
WHERE sales_rank <= 10;

在这个示例中,sales_data 计算每个销售员的总销售额,ranked_sales 计算销售员的排名,最终查询返回前 10 名销售员。

4.2 数据清理和转换

CTE 可以用于数据清理和转换任务,例如在 ETL 过程中的数据预处理。通过使用 CTE,可以在最终的查询中处理和转换数据。

示例:

WITH cleaned_data AS (
    SELECT TRIM(name) AS cleaned_name, 
           UPPER(email) AS cleaned_email
    FROM raw_data
    WHERE email IS NOT NULL
)
INSERT INTO processed_data (name, email)
SELECT cleaned_name, cleaned_email
FROM cleaned_data;

在这个示例中,cleaned_data CTE 处理和清理原始数据,然后将清理后的数据插入到目标表中。

5. 注意事项

5.1 性能考虑

CTE 在复杂查询中可以提高代码的可读性,但可能会影响性能,特别是在使用递归 CTE 时。要注意优化查询,例如使用适当的索引。

优化建议:

  • 使用索引:在 CTE 参与的列上创建索引,以提高查询性能。
  • 避免不必要的递归:尽量避免不必要的递归查询,以减少性能开销。

5.2 CTE 的作用范围

CTE 的作用范围仅限于定义 CTE 的查询。CTE 定义后,其结果集可以在后续的查询中使用,但不能在其他 CTE 中再次引用。

示例:

WITH first_cte AS (
    SELECT column1 FROM table1
),
second_cte AS (
    SELECT column1 FROM first_cte  -- 错误,不能在 second_cte 中引用 first_cte
    UNION
    SELECT column2 FROM table2
)
SELECT * FROM second_cte;

6. 总结

CTE 是 MySQL 中一个强大的查询工具,可以帮助用户简化复杂查询、提高代码的可读性和维护性。通过 CTE,用户可以轻松地定义和使用临时结果集,支持递归查询和数据清理。掌握 CTE 的使用方法和最佳实践,对于提高 SQL 查询的效率和组织性至关重要。在实际应用中,合理使用 CTE 可以显著提升数据分析和处理的能力。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
17天前
|
关系型数据库 MySQL
mysql 使用CTE写法
mysql 使用CTE写法
|
10月前
第18章_MySQL8新特性之CTE(公用表表达式)
第18章_MySQL8新特性之CTE(公用表表达式)
66 0
|
SQL 存储 关系型数据库
Mysql数据库基础第八章:窗口函数和公用表表达式(CTE)
# 1.窗口函数 MySQL从8.0版本开始支持窗口函数。窗口函数的作用类似于在查询中对数据进行分组,不同的是,分组操作会把分组的结果聚合成一条记录,而窗口函数是将结果置于每一条数据记录中。
Mysql数据库基础第八章:窗口函数和公用表表达式(CTE)
|
SQL 弹性计算 关系型数据库
PostgreSQL 12 preview - CTE 增强,支持用户语法层控制 materialized 优化
标签 PostgreSQL , CTE , materialized , not materialized , push down 背景 PostgreSQL with 语法,能跑非常复杂的SQL逻辑,包括递归,多语句物化计算等。 在12以前的版本中,WITH中的每一个CTE(common table express),都是直接进行物化的,也就是说外层的条件不会推到CTE(物化节点)里
934 0
|
MySQL 关系型数据库 内存技术
MySQL · 新特性分析 · CTE执行过程与实现原理
众所周知,Common table expression(CTE)是在大多数的关系型数据库里都存在的特性,包括ORACLE, SQLSERVER,POSTGRESQL等,唯独开源数据库老大MySQL缺失。CTE作为一个方便用户使用的功能,原本是可以利用普通的SQL语句替代的,但是对于复杂的CTE来说,要模拟出CTE的效果还是需要很大的功夫。如果考虑性能那就更是难上加难了。2013年Guilhem
4172 1
|
传感器 SQL 并行计算
【重新发现PostgreSQL之美】 - 6 index链表跳跳糖 (CTE recursive 递归的详细用例)
大家好,这里是重新发现PostgreSQL之美 - 6 index链表跳跳糖 (CTE recursive 递归的详细用例)
|
SQL 分布式计算 并行计算
PostgreSQL 并行计算解说 之29 - parallel 递归查询, 树状查询, 异构查询, CTE, recursive CTE, connect by
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan parallel index scan
243 0
|
SQL 关系型数据库 MySQL
MySQL8.0之CTE(公用表表达式)
MySQL8.0 CTE 通用表达式
3303 1
|
关系型数据库 MySQL
干货 | 解读MySQL 8.0新特性:CTE
CTE也就是common table expressions,是SQL标准里的语法,很多数据库都能够支持,MySQL也在8.0版本里加入了CTE功能。本文主要简单的介绍下该语法的用法,由于笔者对server层了解不深,本文不探讨代码层。
1696 0