データベース - SQL 基本構文 - 重複データを削除する

クラウディア 
1. 概要
2. Oracle の場合
3. MySQL の場合
4. postgreSQL の場合

1. 概要

 こんなバカなことになったのは、わたしくらいのものかと思っていたら、検索したら、例題が載っていたので、こんなことになることも少なからずあるのだとわかりました。  わたしのケースは、何度かデータベースを移植しているうちにこうなっちゃったようです。  そもそも、テーブルにプライマリキーを作成していなかったっけ?  と驚くばかりなのですが。  同じ値を持つレコードが4つずつ存在しているのです。

2. Oracle の場合

 Oracle ではどうやるか・・・。  「重複レコードの削除方法 - オラクル・Oracleをマスターするための基本と仕組み」にありました。  残すレコードを抽出するやり方は、何やら難しそうですが。  そもそも同じデータなのでどれかが残れば構わないというやり方が

DELETE FROM テーブル T1
WHERE ROWID >
(
	SELECT MIN(ROWID) FROM テーブル T2
	WHERE
			T1.カラム1 = T2.カラム1
		AND T1.カラム2 = T2.カラム2
);
 これは簡単。  Oracle の場合、ROWID なるものが存在するのね。

3. MySQL の場合

 MySQL の例は「[SQL]重複データを1件だけ残して削除する方法」にありました。

DELETE FROM テーブル
 WHERE ID NOT IN
 (
  SELECT TMP1.ID FROM (
    SELECT MIN(ID) AS ID
    FROM テーブル
    GROUP BY TMP1.カラム1, TMP1.カラム2
  ) AS TMP1
 );
 だそうで。  MySQL には「ID」ってのが存在するのか、カラム名なのかちょっと不明ですが、調べる元気がないので次に進みます。

4. postgreSQL の場合

 postgreSQL の例は「重複したレコードを1件だけ残して削除したい」にありました。  いくつか方法が提示されていましたが。  とても一般的とは思えませんが、postgreSQL の 9.1 以降だと WITH というのを使ってできるそうで

WITH TMP AS(DELETE FROM テーブル RETURNING *)
INSERT INTO
	テーブル
SELECT DISTINCT * FROM TMP;
 何やら呪文のようですが。  用心のためバックアップをとっておいて実行してみました。  結果は・・・満足のいくものが得られました。  重複がなくなった時点でプライマリキーを設定しました。