MySQL CTE:SQL查询新模式

前言

本文将为开发者系统解析MySQL 8.0引入的CTE特性。通过真实业务场景案例,您将掌握:

  1. 如何用CTE重构嵌套噩梦般的SQL语句
  2. 递归查询实现树形结构遍历的核心方法
  3. 通过查询复用提升30%以上执行效率的技巧
  4. CTE在复杂业务场景下的最佳实践方案

1、成果收益

本最佳实践已取得的成果或预期收益。

简单说,简化了复杂的SQL查询,提升了复杂查询的可读性和复用性。

2、背景

讲述一下问题或痛点,为什么要做这件事。

计费规则根据险种进行数据统计,计费规则从地区到具体险种配置,地区-计费-参保方案-参保方案详情,层级深,关系一层套一层,很多表数据需要复用,只能反反复复的查询。最后写出一个层层嵌套的SQL,看也看不懂,改也改不动。

传统方案面临三大难题:

  1. 嵌套黑洞:5层以上子查询导致SQL可读性断崖式下降
  2. 重复炼狱:相同子查询在多个地方重复出现
  3. 调试噩梦:修改一个字段需要追踪多级嵌套

3、什么是CTE

公共表表达式(Common Table Expression,简称 CTE),CTE 是在SQL查询中定义的一个临时结果集,CTE 通常用于

    • 多层嵌套子查询的简化
    • 递归查询(如树形结构遍历,MySQL 8.0.1+支持递归CTE)
    • 多次复用同一子查询结果

CTE 的定义部分类似于创建一个临时视图,但其生命周期仅限于当前查询。通过 WITH 创建临时命名结果集,WITH 子句更轻量,适合在单个查询中复用中间结果,提升复杂查询的可读性和复用性。

4、CTE如何使用

基本语法
复制代码
WITH cte_name AS (
    -- 子查询
    SELECT ...
)
SELECT ...
FROM cte_name;
  • cte_name:CTE 的名称,就是临时表的名称。
  • 子查询:定义 CTE 的结果集。
  • 后续查询:可以引用 CTE 名称。

注意with是不需要分号结尾的,当分号出现时就意味着当前的SQL生命周期已经结束了。

多个 CTE 的使用

可以在一个 WITH 子句中定义多个 CTE,用逗号分隔。

复制代码
WITH 
cus_totals AS (
    SELECT cus_id, SUM(amount) AS total_amount
    FROM orders
    GROUP BY cus_id
),
latest_orders AS (
    SELECT cus_id, MAX(order_date) AS latest_date
    FROM orders
    GROUP BY cus_id
)
SELECT t.cus_id, t.total_amount, l.latest_date
FROM cus_totals t
JOIN latest_orders l ON t.cus_id = l.cus_id;
示例:
  1. 第一个 CTE:计算每个客户的订单总金额。
  2. 第二个 CTE:计算每个客户的最新订单日期。
  3. 最终查询:连接两个 CTE,生成结果。

5、经验总结

主要用于数据导出的场景,更方便多表查询的场景。

相关推荐
小猿姐4 小时前
实测对比:哪款开源 Kubernetes MySQL Operator 最值得用?(2026 深度评测)
数据库·mysql·云原生
倔强的石头_6 小时前
从 “存得下” 到 “算得快”:工业物联网需要新一代时序数据平台
数据库
TDengine (老段)7 小时前
TDengine IDMP 可视化 —— 分享
大数据·数据库·人工智能·时序数据库·tdengine·涛思数据·时序数据
GottdesKrieges7 小时前
OceanBase数据库备份配置
数据库·oceanbase
SPC的存折8 小时前
MySQL 8组复制完全指南
linux·运维·服务器·数据库·mysql
运维行者_8 小时前
OpManager MSP NetFlow Analyzer集成解决方案,应对多客户端网络流量监控挑战
大数据·运维·服务器·网络·数据库·自动化·运维开发
炸炸鱼.9 小时前
Python 操作 MySQL 数据库
android·数据库·python·adb
softshow10269 小时前
Etsy 把 1000 个 MySQL 分片迁进 Vitess
数据库·mysql
Ronaldinho Gaúch10 小时前
MySQL基础
数据库·mysql
不剪发的Tony老师10 小时前
Noir:一款键盘驱动的现代化数据库管理工具
数据库·sql