当前位置: 首页 > news >正文

MySQL: with as与with RECURSIVE如何混合使用?

文章目录

  • 一、with用法系列文章
  • 二、前言
  • 三、MySQL 普通CTE与递归CTE混合使用的严格规则
  • 四、解决方案
    • 4.1、方法1:嵌套查询
    • 4.2、方法2:使用临时表
    • 4.3、方法3:分开执行(应用层处理)

本文主要探讨mysqlwith普通cte递归cte如何混合使用。

一、with用法系列文章

关于with用法与with RECURSIVE的用法可以参考本人的另外两篇博文。

  • 《sql中with as用法/with-as 性能调优/with用法》
  • 《MYSQL的(WITH RECURSIVE)递归查询》

二、前言

在使用with RECURSIVE 递归查询的过程中,发现有一段sql是公共的,因此想把这部分sql提取出去,当做临时表。 with as子查询就可以当做临时表,所以我就在想能不能先用with as把公共部分查询成临时表,后面再跟着with RECURSIVE 递归查询。即with aswith RECURSIVE 混合使用。

经测试后发现先普通CTE再递归CTE时sql报错 ,所以我想知道是否能混合使用,本文就是来讨论这个问题。

sql示例如下:

-- 查询任务2子节点
WITH RECURSIVE cte AS (SELECT r.id,r.project_code, r.code, r.name,r.parent_project_code,r.parent_codeFROM t_ds_process_dependent_relation rinner join t_ds_process_definition d on r.project_code = d.project_code and r.code = d.code and r.version = d.versionWHERE r.code = 18418446171042 -- 任务2UNION ALLSELECT t.id,t.project_code, t.code, t.name,t.parent_project_code,t.parent_codeFROM t_ds_process_dependent_relation tinner join t_ds_process_definition d on t.project_code = d.project_code and t.code = d.code and t.version = d.versionINNER JOIN cte c ON t.parent_project_code = c.project_code and t.parent_code = c.code
)
SELECT * FROM cte;

在这里插入图片描述

在我的设想里,我想把公共部分提取成普通CTE, 然后在递归CTE中引用,但是这种语法在mysql中是错误的

错误SQL如下:

with relation as ( -- 普通CTESELECT r.id,r.project_code, r.code, r.name,r.parent_project_code,r.parent_codeFROM t_ds_process_dependent_relation rinner join t_ds_process_definition d on r.project_code = d.project_code and r.code = d.code and r.version = d.version),RECURSIVE cte AS ( -- 递归CTESELECT id,project_code, code, name,parent_project_code,parent_codeFROM relationWHERE code = 18418446171042 -- 任务2UNION ALLSELECT t.id,t.project_code, t.code, t.name,t.parent_project_code,t.parent_codeFROM relation tINNER JOIN cte c ON t.parent_project_code = c.project_code and t.parent_code = c.code
)
SELECT * FROM cte;

三、MySQL 普通CTE与递归CTE混合使用的严格规则

在 MySQL 中,不可以 先定义普通 CTE 再定义递归 CTE。这是 MySQL 与某些其他数据库(如 PostgreSQL)的一个重要语法差异。

MySQL 的严格规则

  • 必须将 RECURSIVE 关键字紧跟在 WITH 之后

  • 第一个 CTE 必须是递归 CTE(如果使用了 RECURSIVE 关键字)

  • 所有 CTE(包括普通 CTE)都必须放在同一个 WITH RECURSIVE 块中

正确写法示例:

WITH RECURSIVE-- 必须先定义递归CTErecursive_cte AS (-- 基础部分SELECT ...UNION ALL-- 递归部分SELECT ... FROM recursive_cte ...),-- 然后才能定义普通CTEnormal_cte AS (SELECT ... FROM ...)-- 主查询
SELECT ... FROM recursive_cte JOIN normal_cte ...

错误写法示例:

-- 这样写会报错!
WITHnormal_cte AS (SELECT ...),  -- 先普通CTERECURSIVE                   -- 后RECURSIVErecursive_cte AS (SELECT ...)
SELECT ...

四、解决方案

如果确实需要先处理普通 CTE 再处理递归 CTE,可以考虑以下方法:

4.1、方法1:嵌套查询

WITH RECURSIVE-- 将普通CTE的逻辑嵌入到递归CTE的基础部分recursive_cte AS (-- 基础部分包含普通CTE逻辑WITH normal_cte AS (SELECT ...)SELECT ... FROM normal_cte WHERE ...UNION ALL-- 递归部分SELECT ... FROM recursive_cte ...)
SELECT ... FROM recursive_cte;

4.2、方法2:使用临时表

-- 先创建临时表存储普通CTE结果
CREATE TEMPORARY TABLE temp_normal AS
SELECT ... FROM ...;-- 然后使用递归CTE
WITH RECURSIVE recursive_cte AS (SELECT ... FROM temp_normal ...
)
SELECT ... FROM recursive_cte;-- 最后删除临时表
DROP TEMPORARY TABLE temp_normal;

4.3、方法3:分开执行(应用层处理)

-- 第一个查询:执行普通CTE
SET @var = (SELECT ... FROM ...);-- 第二个查询:执行递归CTE
WITH RECURSIVE recursive_cte AS (SELECT ... WHERE ... = @var
)
SELECT ... FROM recursive_cte;
http://www.dtcms.com/a/306490.html

相关文章:

  • 【算法】十大排序算法超深度解析,从数学原理到汇编级优化,涵盖 15个核心维度
  • 专题:2025机器人产业技术图谱与商业化指南|附130+份报告PDF、数据汇总下载
  • C++实战:抖音级视频应用开发精髓
  • LazyLLM教程 | 第2讲:10分钟上手一个最小可用RAG系统
  • [极客时间]LangChain 实战课 -----|(11) 记忆:通过Memory记住客户上次买花时的对话细节
  • macOS 设置 Claude Code
  • 02 NameServer是如何管理Broker集群的
  • 【STM32-HAL】 SPI通信与Flash数据写入实战
  • Elasticsearch(ES)基础语法(笔记)(持续更新)
  • MySQL索引和事务笔记
  • 如何通过项目管理系统提升交付率
  • Kafka 重复消费与 API 幂等消费解决方案
  • IO复用实现并发服务器
  • 【PZ7020-StarLite 入门级开发板】——FPGA 开发的理想起点,入门与工业场景的双重优选
  • 【工具】jsDelivr CDN完全指南:免费高速的开源项目CDN服务
  • Apache Ignite 与 Spring Boot 集成
  • Linux 进程管理与计划任务设置
  • 【Dv3admin】ORM数据库无法查询的问题
  • 如何修改VM虚拟机中的ip
  • opengauss数据库安装及测试
  • 【C语言】深度剖析指针(二):指针与数组,字符,函数的深度关联
  • SpringBoot中ResponseEntity的使用详解
  • .NET报表控件ActiveReports发布v19.0——正式兼容 .NET 9
  • 动态爱心视觉特效合集(含 WebGL 与粒子动画)
  • 传输层协议UDP与TCP
  • 微算法科技MLGO突破性的监督量子分类器:纠缠辅助训练算法为量子机器学习开辟新天地
  • G9打卡——ACGAN
  • ​​咖啡艺术的数字觉醒:Deepoc具身智能如何重塑咖啡机器人的“风味直觉”
  • Android基础(二)了解Android项目
  • Android补全计划 TextView设置文字不同字体和颜色