1. ホーム
  2. データベース
  3. マイサク

[解決済み】MySQL エラー 1093 - FROM 句で更新のターゲット テーブルを指定できません。

2021-12-29 03:11:02

質問

私はテーブルを持っています story_category のデータベースで、破損したエントリがあります。次のSQLクエリは、破損したエントリを返します。

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 はテーブルを 2 つの異なるものとして認識し、破壊的な変更を実行できるようになります。

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から。 原文はNabbleに掲載されています。 ここでは、その言い換えと拡張を行います。