テーブル内の重複の問題はSQLで最も古くから存在するものであり、特にインターネットサービスの急増と大規模データの移行に伴って悪化しています。最初は手作業で問題を解決していました:スクリプトを使って重複を1つずつ見つけて削除していましたが、データ量の増加につれてこのアプローチは非効率になってきました。
問題:不注意なデータのロードや移行、または故障により、同じキー特性(たとえば、メールアドレスやパスポート)がある数万行が生成されることがよくあります。これにより、統合時のエラー、不正確な分析、顧客の信頼の喪失が引き起こされます。
解決策:グループ化およびウィンドウ関数を使用して重複に関するレポートを作成し、「正しい」1つのレコードのみを保持して重複を削除する; キーフィールドに対して制約(UNIQUE)を追加し、定期的な監査を必須にします。
コード例
WITH Duplicates AS ( SELECT email, COUNT(*) AS cnt FROM users GROUP BY email HAVING COUNT(*) > 1 ) SELECT u.* FROM users u JOIN Duplicates d ON u.email = d.email ORDER BY u.email, u.id;
重複を削除する(最小のidを持つ行を残す):
DELETE FROM users WHERE id NOT IN ( SELECT MIN(id) FROM users GROUP BY email );
主な特徴:
DISTINCTを使用してテーブルから重複を削除できますか?
いいえ、DISTINCTは選択(SELECT)のみに機能し、テーブルから行を削除することはありません。DELETEまたはINSERT ... SELECTとDISTINCTを使用して新しいクリーンなテーブルを作成する必要があります。
DELETE ... WHERE id NOT IN (SELECT MIN(id) ...) コマンドはすべての重複を確実に削除しますか?
いいえ、キー列にNULLがある場合、そのクエリはNULL値の比較の特性により、誤って重複を残す可能性があります。
一意のINDEXを作成するだけで、二度と重複が発生しないでしょうか?
いいえ、インデックスは新しい重複の挿入を防ぐだけであり、すでにテーブル内に存在する重複には影響しません。
CRMシステムが異なるソースからユーザーをコピーし、emailの一意性を考慮せず、データベースには50000の重複があります。UNIQUEインデックスを一括追加すると失敗し、サービスがダウンします。
利点:
欠点:
エンジニアは専門のレポートを通じて定期的に重複を分析し、データベースを整理し、一意のインデックスを作成します。新しいデータを移行する前に検証を行います。
利点:
欠点: