MySQLが重複行を削除する方法

How Mysql Delete Duplicate Rows



MySQLは、行と列を持つテーブルにデータを格納するリレーショナルデータセットです。ただし、データベースに保存されているデータには、アプリケーションまたはユーザーのエラーが原因で重複した値が含まれている可能性があります。

このチュートリアルでは、MySQLデータベースの重複行を削除してデータベースのサイズを縮小し、サーバーのパフォーマンスを向上させる方法を学習します。







続行する前に、次のことを前提としています。



  1. MySQLがインストールされ、システムで実行されています
  2. データベースへのルートアクセス権があります。
  3. 実験またはテスト用のデータベースにアクセスできます

ノート :このガイドで提供されている概念を試すためにサンプルデータベースが必要な場合は、Sakilaデータベースを検討するか、このガイドで使用されているデータベースのコピーをダウンロードしてください。



リソースは以下に提供されています:





基本的な使用法

始める前に、テスト目的で重複する値を含むテーブルを意図的に作成します。このアクションを実行するためのSQLクエリは次のとおりです。

使用する 世界;
落とす テーブル もしも 存在する ユーザー;
作成 テーブル ユーザー((id INT 主キー いいえ ヌル 自動増加 ユーザー名 VARCHAR ((10)。 いいえ ヌル フルネーム VARCHAR ((20)。Eメール VARCHAR ((255)。 いいえ ヌル )。;
入れる の中へ ユーザー((ユーザー名フルネームEメール)。
((「乙女座」 「クロード・M・モリ」 '[メール保護]')。
(('押す' 「ティファニーG.ベイリー」 '[メール保護]')。
(('ロケット' 「クリストファーS.ペイトン」 '[メール保護]')。
((「darkmatter」 「パトリシアJ.フォックス」 '[メール保護]')。
(('主題' 「フェイ・H・ハートリー」 '[メール保護]')。
((「darkmatter」 「パトリシアJ.フォックス」 '[メール保護]')。
(('ロケット' 「クリストファーS.ペイトン」 '[メール保護]')。
((「アルテミス」 「ウェズリーC.ディラード」 '[メール保護]')。;

ニーズに合わせて、上記のクエリを自由に変更してください。また、エラーを回避するために、データベース(ワールド)が作成されていることを確認する必要があります。



ここで、テーブル内のすべてのデータをユーザー名順に取得すると、次のように重複が表示されます。

mysql>> 使用する 世界;
データベース かわった
mysql>> 選択する * から ユーザー 注文者 ユーザー名;
+ ---- + ------------ + ----------------------- + ------- ---------------- +
|id|ユーザー名|フルネーム|Eメール|
+ ---- + ------------ + ----------------------- + ------- ---------------- +
| 8 |アルテミス|ウェズリーC.ディラード|[メール保護]|
| 4 |darkmatter|パトリシア・J・フォックス|[メール保護]|
| 6 |darkmatter|パトリシア・J・フォックス|[メール保護]|
| 2 |押す|ティファニーG.ベイリー|[メール保護]|
| 5 |主題|フェイ・H・ハートリー|[メール保護]|
| 3 |ロケット|クリストファーS.ペイトン|[メール保護]|
| 7 |ロケット|クリストファーS.ペイトン|[メール保護]|
| 1 |乙女座|クロード・M・モリ|[メール保護]|
+ ---- + ------------ + ----------------------- + ------- ---------------- +

上の表からわかるように、2つの重複する値があり、理由もなくデータベースが大きくなり、速度が低下します。

これらの値を削除する方法を学びましょう。

#1-結合の削除

データベース内の重複行を削除する1つの方法は、MySQL DELETEJOINステートメントを使用することです。ただし、クエリはIDを使用して重複する値を削除します。

たとえば、上記のusersテーブルの重複する値を削除するには、次のように入力します。

消去 表1 から ユーザーtable1 内側 加入 ユーザーtable2 どこ table1.id<table2.id table1.email=table2.email;

上記のクエリを実行すると、以下の出力に示すように、重複する値が削除されます。

mysql>> 消去 表1 から ユーザーtable1 内側 加入 ユーザーtable2 どこ table1.id<table2.id table1.email=table2.email;
クエリOK 2影響を受ける行((0.01)。

mysql>> 選択する * から ユーザー 注文者 ユーザー名;
+ ---- + ------------ + ----------------------- + ------- ---------------- +
|id|ユーザー名|フルネーム|Eメール|
+ ---- + ------------ + ----------------------- + ------- ---------------- +
| 8 |アルテミス|ウェズリーC.ディラード|[メール保護]|
| 6 |darkmatter|パトリシア・J・フォックス|[メール保護]|
| 2 |押す|ティファニーG.ベイリー|[メール保護]|
| 5 |主題|フェイ・H・ハートリー|[メール保護]|
| 7 |ロケット|クリストファーS.ペイトン|[メール保護]|
| 1 |乙女座|クロード・M・モリ|[メール保護]|
+ ---- + ------------ + ----------------------- + ------- ---------------- +

#2 – Row_Number()関数

実装できる2番目のメソッドは、MySQLのrow_number()関数を使用することです。この機能は、MySQLバージョン8以降でサポートされています。

これは、各行に順次int値を割り当て、重複する値を含む行が1より大きい値を取得することによって機能します。

この関数の詳細については、以下のリソースを使用してください。

https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html#function_row-number

重複する値を持つ行のIDを返す以下のクエリについて考えてみます。

選択する id から (( 選択する idROW_NUMBER(()。以上(( パーティション ユーザー名で 注文者 ユーザー名)。 なので row_var から ユーザー)。t1 どこ row_var>> 1;

上記のクエリを実行すると、以下の出力に示すようなIDのリストが表示されます。

+ ---- +
|id|
+ ---- +
| 6 |
| 7 |
+ ---- +
2 設定 ((0.01)。

値を削除する場合は、以下に示すように、SELECTステートメントをDELETEステートメントに置き換えるだけです。

消去 から ユーザー どこ id (( 選択する id から (( 選択する idROW_NUMBER(()。以上(( パーティション ユーザー名で 注文者 ユーザー名)。 なので row_var から ユーザー)。t1 どこ row_var>> 1)。;

最後に、SELECTステートメントを使用して、重複する値が削除されていることを確認できます。

mysql>> 選択する * から ユーザー 注文者 ユーザー名;
+ ---- + ------------ + ----------------------- + ------- ---------------- +
|id|ユーザー名|フルネーム|Eメール|
+ ---- + ------------ + ----------------------- + ------- ---------------- +
| 8 |アルテミス|ウェズリーC.ディラード|[メール保護]|
| 4 |darkmatter|パトリシア・J・フォックス|[メール保護]|
| 2 |押す|ティファニーG.ベイリー|[メール保護]|
| 5 |主題|フェイ・H・ハートリー|[メール保護]|
| 3 |ロケット|クリストファーS.ペイトン|[メール保護]|
| 1 |乙女座|クロード・M・モリ|[メール保護]|
+ ---- + ------------ + ----------------------- + ------- ---------------- +

結論

このチュートリアルでは、データベースから重複する値を削除する2つの方法について説明しました。大規模なデータベース、特に一般的に使用されているデータベースには、外部インポートやその他のエラーからの重複値が多数含まれている場合があります。したがって、アプリケーションが最適に実行されるようにするには、重複する値をパージし続ける必要があります。