更新、削除対象の条件に、自己テーブルを参照するサブクエリーを利用するクエリーを実行するとエラーが発生します。
この場合の解決策は色々とありますが、今回はコーディングのみで手っ取り早く解決できる方法を記載しています。
サブクエリーにエイリアスを利用する方法
エラーが発生する更新、削除クエリー
下記のような更新、削除対象の条件に、自己テーブルを参照するサブクエリーを条件とするクエリーを実行するとエラーが発生します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
delete from user_information_details where id in ( select ss.id from user_informations ui inner join user_information_details uid on (uid.user_information_id = ui.id) where ui.created_at like '2018%' ): |
※セキュリティーの関係上、予約後は全角文字に変換しています。
エラーメッセージ
1 2 3 |
ERROR 1093 (HY000): You can't specify target table 'user_information_details' for update in FROM clause |
エラーを回避する更新、削除クエリー
このエラーの原因は、サブクエリのFROM句と、更新対象のテーブルに、同じテーブルが使えないこととなります。
これを解決するには、上記のSQLを少しだけ修正します。
具体的には、サブクエリーのSELECT結果を、エイリアス指定するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
delete from user_information_details where id in ( select temp1.id from ( select ui.id from user_informations ui inner join user_information_details uid on (uid.user_information_id = ui.id) where ui.created_at like '2018%' ) as temp1 ); |
※セキュリティーの関係上、予約後は全角文字に変換しています。
一時テーブルを利用する方法
更新対象となる自己参照テーブルの更新キーを、一時テーブルに格納する方法もあります。
一時テーブルとなるため、一連のトランザクションが終わると、自動的に消えます。
そのため、いつの間にか不要テーブルが増えていたということも防止出来ます。
まとめ
データベースのレコードを更新する場合に、自己テーブルを参照するサブクエリーを利用して、削除、更新する局面は、意外と多いものです。
解決法はたくさんありますが、このような条件を利用したデータ更新をする場合には、緊急性の高い作業が多いと思います。
ぜひ、作業効率をよくするために参考にして下さい。