我的数据库中有一个story_category包含损坏条目的表。下一个查询返回损坏的条目:
story_category
SELECT * FROM story_category WHERE category_id NOT IN ( SELECT DISTINCT category.id FROM category INNER JOIN story_category ON category_id=category.id);
我试图删除它们执行:
DELETE FROM story_category WHERE category_id NOT IN ( SELECT DISTINCT category.id FROM category INNER JOIN story_category ON category_id=category.id);
但我得到下一个错误:
1093 - 您不能在 FROM 子句中指定目标表 ‘story_category’ 进行更新
我该如何克服呢?
更新:这个答案涵盖了一般错误分类。 有关如何最好地处理 OP 的确切查询的更具体的答案,请参阅此问题的其他答案
在 MySQL 中,您不能修改在 SELECT 部分中使用的同一个表。 此行为记录在: http ://dev.mysql.com/doc/refman/5.6/en/update.html
也许您可以将表连接到自身
如果逻辑足够简单以重新塑造查询,则丢失子查询并将表连接到自身,使用适当的选择标准。这将导致 MySQL 将表视为两个不同的事物,从而允许进行破坏性更改。
UPDATE tbl AS a INNER JOIN tbl AS b ON .... SET a.col = b.col
或者,尝试将子查询更深地嵌套到 from 子句中......
如果您绝对需要子查询,则有一种解决方法,但由于几个原因,它很难看,包括性能:
UPDATE tbl SET col = ( SELECT ... FROM (SELECT.... FROM) AS x);
FROM 子句中的嵌套子查询会创建一个 隐式临时表 ,因此它不会算作您正在更新的同一张表。
…但要注意查询优化器
但是,请注意,从MySQL 5.7.6起,优化器可能会优化子查询,但仍然会给您错误。幸运的是,该 optimizer_switch变量可用于关闭此行为;尽管我不建议将此作为短期修复或一次性小型任务。
optimizer_switch
SET optimizer_switch = 'derived_merge=off';
感谢 Peter V. Mrch在评论中提供的这个建议。
示例技术来自 Baron Schwartz,最初在 Nabble 上发表,在此进行了释义和扩展。