You cannot update a table and select directly from the same table in a subquery.
mysql官方文档中有这句话,我们不能在一个语句中先在子查询中从某张表查出一些值,再update这张表。
比如:
mysql> UPDATE items
SET
retail = retail * 0.9
WHERE
id IN (
SELECT
id
FROM
items
WHERE
retail / wholesale >= 1.3
AND quantity > 100
);复制
这个语句执行的时候会报错:ERROR 1093 (HY000): You can't specify target table 'items' for update in FROM clause
针对这种报错,有两种方法解决:多表更新和中间表
方法一 多表更新
我们可以通过多表更新来解决这个问题,连表时一张表是实际要更新的表,另一张表是原来的子查询派生出来的表,我们使用别名引用派生表。比如上面的例子中的sql,可以改写成如下写法:
update items,
(
SELECT
id
FROM
items
WHERE
retail / wholesale >= 1.3
AND quantity > 100
) a
set
retail = items.retail * 0.9
where
items.id = a.id复制
方法二 中间表
中间表的含义是将子查询再包一层,比如上面的语句可以改写成:
UPDATE items
SET
retail = retail * 0.9
WHERE
id IN (
select
id
from
(
SELECT
id
FROM
items
WHERE
retail / wholesale >= 1.3
AND quantity > 100
) aa
);复制
需要注意的是,mysql优化器可能会优化子查询,这时候可能仍然会抛出错误。我们可以使用optimizer_switch变量关闭这种行为;
#将derived_merge标志设置为off
SET optimizer_switch='derived_merge=off';复制
derived_merge是MySQL中的查询优化技术之一,用于控制派生表合并(derived merge)优化的行为。在MySQL中,当执行复杂的查询时,可能会涉及到派生表,即在查询中使用子查询作为临时表。派生表合并是一种优化技术,它尝试将多个派生表合并为一个更简单的查询结构,以提高查询性能。
参考:https://fanyi.youdao.com/index.html#/ https://dev.mysql.com/doc/refman/8.0/en/update.html
点个“赞 or 在看” 你最好看!

👇👇👇 谢谢各位老板啦!!!
文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
墨天轮个人数说知识点合集
JiekeXu
427次阅读
2025-04-01 15:56:03
Oracle SQL 执行计划分析与优化指南
Digital Observer
424次阅读
2025-04-01 11:08:44
MySQL数据库当前和历史事务分析
听见风的声音
419次阅读
2025-04-01 08:47:17
MySQL 生产实践-Update 二级索引导致的性能问题排查
chengang
380次阅读
2025-03-28 16:28:31
MySQL 9.3 正式 GA,我却大失所望,新特性亮点与隐忧并存?
JiekeXu
344次阅读
2025-04-15 23:49:58
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
344次阅读
2025-04-17 17:02:24
9.9 分高危漏洞,尽快升级到 pgAdmin 4 v9.2 进行修复
严少安
341次阅读
2025-04-11 10:43:23
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
326次阅读
2025-04-15 14:48:05
云和恩墨杨明翰:安全生产系列之MySQL高危操作
墨天轮编辑部
304次阅读
2025-03-27 16:45:26
火焰图--分析复杂SQL执行计划的利器
听见风的声音
303次阅读
2025-04-17 09:30:30