可能な重複:
MySQLの重複行を削除する
MySQLテーブルからすべての重複データを削除する方法
たとえば、次のようになります。
SELECT * FROM names;
+----+--------+
| id | name |
+----+--------+
| 1 | google |
| 2 | yahoo |
| 3 | msn |
| 4 | google |
| 5 | google |
| 6 | yahoo |
+----+--------+
SELECT
クエリであれば、SELECT DISTINCT name FROM names;
を使用します。
重複を削除してそれぞれ1つのレコードだけを保持するために、これをDELETE
でどのようにしたらよいでしょうか。
編集者警告:この解決策は計算上非効率的で大きなテーブルへの接続を断念するかもしれません。
NB - あなたのテーブルのテストコピーに対して最初にこれを実行するには、必要を使用してください。
実行したとき、AND n1.id <> n2.id
も含めない限り、テーブルのすべての行が削除されることがわかりました。
行を最小のid
値で保持したい場合は、次のようにします。
DELETE n1 FROM names n1, names n2 WHERE n1.id > n2.id AND n1.name = n2.name
行を最も高いid
値で保持したい場合は、次のようにします。
DELETE n1 FROM names n1, names n2 WHERE n1.id < n2.id AND n1.name = n2.name
私はMySQL 5.1でこの方法を使いました
他のバージョンについてはわかりません。
更新:重複を削除するためにグーグルを使っている人はここで終わる
OPの質問はDELETE
に関するものですが、INSERT
とDISTINCT
を使う方がはるかに速いことに注意してください。 800万行のデータベースの場合、以下のクエリは13分かかりましたが、DELETE
を使用した場合、2時間以上かかりましたが、完了しませんでした。
INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
SELECT DISTINCT cellId,attributeId,entityRowId,value
FROM tableName;
行を最小のid
値で保持したい場合は、次のようにします。
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MIN(n.id)
FROM NAMES n
GROUP BY n.name) x)
最も高いid
値が必要な場合は、次のようにします。
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MAX(n.id)
FROM NAMES n
GROUP BY n.name) x)
サブクエリ内のサブクエリはMySQLに必要です、さもないと1093エラーが発生します。