MySQL で “ERROR 1093 (HY000): You can’t specify target table ‘xxxx’ for update in FROM clause” エラーが発生する

IT

はじめに

MySQL の”ERROR 1093 (HY000): You can’t specify target table ‘xxxx’ for update in FROM clause”エラーを回避する方法についてまとめます。

環境

以下が今回の環境です。DB は MySQL を使用します。

$ python -V
Python 3.7.10
$ pip list | grep PyMySQL
PyMySQL               1.0.2

$ mysql --version
mysql  Ver 8.0.29 for Linux on x86_64 (MySQL Community Server - GPL)

事象

今回、以下のデータを使用します。

mysql> select * from dogs;
+------+----------+---------+-------+
| id   | name     | owner   | birth |
+------+----------+---------+-------+
|    1 | poota    | masawai | 8/23  |
|    2 | pooko    | masawai | 8/23  |
|    3 | torapoo  | masawai | 8/23  |
|    4 | kachapoo | masawai | 8/23  |
|    5 | dospoo   | masawai | 8/23  |
+------+----------+---------+-------+

mysql> select * from dogs_mf;
+------+--------+
| id   | gender |
+------+--------+
|    1 | m      |
|    2 | f      |
|    3 | m      |
|    4 | m      |
|    5 | m      |
+------+--------+

以下の SQL を実行すると、エラーが発生します。

mysql> DELETE
    -> FROM
    ->     dogs
    -> WHERE
    ->     id NOT IN(
    ->         SELECT
    ->             dogs.id
    ->         FROM
    ->             dogs
    ->             JOIN
    ->                 dogs_mf
    ->             ON  dogs.id = dogs_mf.id
    ->         WHERE
    ->             gender = 'f'
    ->     );                           
ERROR 1093 (HY000): You can't specify target table 'dogs' for update in FROM clause

こちらのエラーについては、公式ドキュメントに記載されています。
サブクエリーの FROM 句と更新のターゲットの両方に同じテーブルを指定していることが原因のようです。

You can use a subquery for assignment within an UPDATE statement because subqueries are legal in UPDATE and DELETE statements as well as in SELECT statements. However, you cannot use the same table (in this case, table t1) for both the subquery FROM clause and the update target.

回避方法

サブクエリの結果を別名として受け取ることでエラーを回避することができます。

mysql> DELETE
    -> FROM
    ->     dogs
    -> WHERE
    ->     id NOT IN(
    ->         SELECT
    ->             id
    ->         FROM
    ->             (
    ->                 SELECT
    ->                     dogs.id
    ->                 FROM
    ->                     dogs
    ->                     JOIN
    ->                         dogs_mf
    ->                     ON  dogs.id = dogs_mf.id
    ->                 WHERE
    ->                     gender = 'f'
    ->             ) temp
    ->     );

おわりに

本記事では MySQL の”ERROR 1093 (HY000): You can’t specify target table ‘xxxx’ for update in FROM clause”エラーを回避する方法についてまとめます。この記事がどなたかの参考になれば幸いです。

参考

コメント