You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 8.0中如何结合CTE使用DELETE与UPDATE语句?

在MySQL 8.0中用CTE执行UPDATE和DELETE的正确姿势

嘿,这个问题我之前踩过坑!MySQL 8.0确实支持在UPDATE/DELETE前加WITH子句,但你不能直接把CTE当作更新/删除的目标——普通CTE在MySQL里是不可更新的,这就是你报错的原因。正确的思路是:用CTE筛选出要操作的行,再关联到原表进行修改。

一、用CTE执行DELETE操作

针对你的test1表,我们可以先用CTE定位要删除的行,再通过关联原表完成删除:

WITH cte_1 AS (
    -- 先筛选出要删除的目标行
    SELECT val_1, val_2 FROM test1 WHERE val_2 = -15
)
DELETE test1
FROM test1
JOIN cte_1 ON test1.val_1 = cte_1.val_1 AND test1.val_2 = cte_1.val_2;

或者用MySQL特有的USING语法,写法更简洁:

WITH cte_1 AS (
    SELECT val_1, val_2 FROM test1 WHERE val_2 = -15
)
DELETE FROM test1
USING cte_1
WHERE test1.val_1 = cte_1.val_1 AND test1.val_2 = cte_1.val_2;

小贴士:如果你的表有主键(比如id列),用主键关联会更安全,避免因重复数据导致误删。比如把关联条件改成test1.id = cte_1.id。

二、用CTE执行UPDATE操作

同理,先通过CTE定位要更新的行,再关联原表修改字段:

WITH cte_1 AS (
    -- 筛选出要更新的目标行
    SELECT val_1, val_2 FROM test1 WHERE val_2 = -15
)
UPDATE test1
JOIN cte_1 ON test1.val_1 = cte_1.val_1 AND test1.val_2 = cte_1.val_2
SET test1.val_2 = 14;

如果你的CTE包含复杂计算(比如需要基于聚合结果更新),只要能关联回原表的唯一标识,这个方法同样适用。

为什么之前的写法报错?

MySQL的CTE本质上是一个临时结果集,默认不属于“可更新视图”范畴,所以你直接DELETE FROM cte_1或UPDATE cte_1会提示目标表不可更新。必须通过关联原表,让数据库明确知道要修改的是原表的数据。

内容的提问来源于stack exchange,提问作者Friedrich Nietzsche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:12:37