一般に、行の重複を防ぐために、テーブルに一意の制約を設定することをお勧めします。ただし、人為的エラー、アプリケーションのバグ、または外部ソースからのクリーンアップされていないデータによって重複行が作成されたデータベースで作業していることに気付く場合があります。このチュートリアルでは、これらの重複する行を見つける方法を説明します。
フォローするには、データベースへの読み取りアクセスと、データベースをクエリするためのツールが必要です。
最初のステップは、重複する行の基準を定義することです。一意にするために2つの列の組み合わせが必要ですか、それとも1つの列で重複を検索するだけですか?この例では、Usersテーブルの2つの列(usernameとemail)で重複を検索しています。
ここで作成する最初のクエリは、テーブルに重複が実際に存在するかどうかを確認するための単純なクエリです。この例では、私のクエリは次のようになります:
SELECT username, email, COUNT(*)
FROM users
GROUP BY username, email
HAVING COUNT(*) > 1
HAVING
WHERE
とは異なり、ここでは重要です 、HAVING
集計関数のフィルター。
行が返される場合は、重複していることを意味します。この例では、結果は次のようになります。
ユーザー名 | メール | カウント |
---|---|---|
ピート | [email protected] | 2 |
ジェシカ | [email protected] | 2 |
マイル | [email protected] | 2 |
前のステップで、クエリは重複のリストを返しました。ここで、重複する行ごとにレコード全体を返します。
これを実現するには、テーブル全体を選択し、それを重複する行に結合する必要があります。クエリは次のようになります:
SELECT a.*
FROM users a
JOIN (SELECT username, email, COUNT(*)
FROM users
GROUP BY username, email
HAVING count(*) > 1 ) b
ON a.username = b.username
AND a.email = b.email
ORDER BY a.email
よく見ると、このクエリはそれほど複雑ではないことがわかります。最初のSELECT
ユーザーテーブルのすべての列を選択するだけで、最初のクエリから複製されたデータテーブルと内部結合します。テーブルをそれ自体に結合しているため、2つのバージョンにラベルを付けるためにエイリアスを使用する必要があります(ここでは、aとbを使用しています)。
このクエリの結果は次のようになります。
id | ユーザー名 | メール |
---|---|---|
1 | ピート | [email protected] |
6 | ピート | [email protected] |
12 | ジェシカ | [email protected] |
13 | ジェシカ | [email protected] |
2 | マイル | [email protected] |
9 | マイル | [email protected] |
この結果セットにはすべての行IDが含まれているため、後で行の重複排除に役立てることができます。