2019/09/03

MySQLで複数カラムの値が重複している行をSELECTしたい

または

MySQLでUnique制約を後付けする時にDuplicateエラーが起きてしまった時の解消法

結論としては、以下のSQLを修正して流し、出てきた重複行を1行だけ残して削除する。
以下のSQLは2カラムの重複を検索する例だが、3カラムにすることも出来る。
SELECT
  *
FROM
  one_table t0
INNER JOIN (
  SELECT
    aaa_id, bbb_id
  FROM
    one_table
  GROUP BY
    aaa_id, bbb_id
  HAVING COUNT(*) >= 2
) t1
ON
  t0.aaa_id = t1.aaa_id
AND
  t0.bbb_id = t1.bbb_id

Unique制約を後付けしなければならない状況とは?

本来 aaa_idカラムとbbb_idカラムは以下のように2つでUniqueであるべきだったが、
aaa_id, bbb_id
    1 ,    1
    2 ,    2
うっかり運用開始時に付け忘れていて、しかもシステムで
aaa_id, bbb_id
    1 ,    1
    1 ,    1
    2 ,    2
    2 ,    2
のように重複させちゃっていて、慌てて後でUnique制約を追加する、ということが不幸にも起きた場合。
すでに重複してしまってると、Uniqueを付けることはできないのでDuplicateエラーが発生する。
そこで、処理時点で重複している行を上記の手順で炙り出し、出てきた重複行を、1行を残して全て消す、という修正をしてからUnique制約を付ける、というお話。全部消すとデータが消えるので注意が必要だ。

サービスを運用してると不幸にも何度か遭遇するので、すぐ呼び出せるようにメモしておく。

0 件のコメント:

コメントを投稿