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、经验总结

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

相关推荐
xmjd msup8 分钟前
mysql的分区表
数据库·mysql
Lyyaoo.8 分钟前
【JAVA Spring面经】Spring 事务失效情况
java·数据库·spring
MeAT ITEM13 分钟前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
dovens17 分钟前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
IOT.FIVE.NO.118 分钟前
claude code desktop cowork报错解决和记录Workspace..The isolated Linux environment ...
linux·服务器·数据库
Rick199326 分钟前
mysql 慢查询怎么快速定位
android·数据库·mysql
科技小花8 小时前
全球化深水区,数据治理成为企业出海 “核心竞争力”
大数据·数据库·人工智能·数据治理·数据中台·全球化
X56619 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python
虹科网络安全10 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
2301_7717172110 小时前
解决mysql报错:1406, Data too long for column
android·数据库·mysql