MySQL 错误 1093 - 无法在 FROM 子句中指定要更新的目标表

我的数据库中有一个表 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 - You can't specify target table 'story_category' for update in FROM clause

我该如何克服这个问题?

最佳答案

更新:此答案涵盖一般错误分类。有关如何最好地处理 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 变量可用于关闭此行为;尽管我不建议将此作为短期修复或一次性小任务。

SET optimizer_switch = 'derived_merge=off';

感谢 Peter V. Mørch在评论中获得此建议。

示例技术来自 Baron Schwartz,originally published at Nabble , 在这里转述和扩展。

https://stackoverflow.com/questions/45494/

相关文章:

mysql - 如何查看表或列的所有外键?

mysql - 如何获取mysql数据库的大小?

MySQL 错误 #1071 - 指定的键太长;最大 key 长度为 767 字节

mysql - 如何从 mysqldump 恢复转储文件?

mysql - 如何在 MySQL 中进行正则表达式替换?

mysql - 禁用 ONLY_FULL_GROUP_BY

mysql - 在 MySQL 中使用 Join 删除

mysql - 如何使用 mysqldump 跳过某些数据库表?

mysql - 安装 mysql2 时出错 : Failed to build gem native

mysql - 在没有单独的 CREATE TABLE 的 SELECT 语句中创建临时表