1. ホーム
  2. mysql

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

2022-01-29 05:26:17

質問

私はテーブルを持っています 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 はテーブルを 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に掲載されています。 ここでは、その言い換えと拡張を行います。