【mysql】重複したカラムなら一行残して残りを削除するサブクエリ

この記事について

環境mysql
目的重複データがあれば一行だけ残して削除するクエリを書く
結果サブクエリの結果をさらにSELECTで包んでAS xと別名を付ければ実行できた

つまずきポイント要約

  • 更新対象と同じテーブルをサブクエリに指定すると「You can’t specify target table」エラーになる

column1に重複データがあれば、一行だけ残して削除するクエリを書いた。

DELETE FROM table_name1 WHERE id in ( SELECT id FROM table_name1 GROUP BY column1 HAVING COUNT(*) >= 2 )

(正確には、このクエリだと二行以上のデータに対し一行だけ削除していて、三行以上ダブっても一行しか消去してない)

事象

しかしmysqlでクエリを実行するとエラーが出る

エラー内容

You can't specify target table 'table_name1' for update in FROM clause

日本語訳

From句においてupdateのためのターゲットテーブル「table_name1」を指定できない
・clause(クローズ)→ 節。句。文節。文の一部分。
・specify → 指定できない。明示できない。

原因

どうもmysqlでは、あるテーブルに対してデータを追加や更新する場合、同じテーブルをサブクエリに使えないらしい。(table_name1が重複)

DELETE FROM table_name1 WHERE id in ( SELECT id FROM table_name1 GROUP BY column1 HAVING COUNT(*) >= 2 )

対処

そこで次のように書き換える。

DELETE FROM table_name1 WHERE id in ( SELECT id FROM (SELECT id FROM table_name1 GROUP BY column1 HAVING COUNT(*) >= 2) AS x )

サブクエリ内で作ったデータを一旦’X’に置き換える。すると制限にひっかからずに期待した結果が手に入る。

関連記事

タイトルとURLをコピーしました