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
相关产品推荐
相关产品推荐

