1つのSQL文でMySQLの重複排除が完了し、1つが保持されます。

1つのSQL文でMySQLの重複排除が完了し、1つが保持されます。

数日前、ある要件に取り組んでいたとき、MySQL で重複レコードをクリーンアップする必要がありました。その時は、コード トラバーサルを使用して書き出すことを考えましたが、複雑すぎると感じたので、SQL ステートメントを使用して問題を解決する必要があると考えました。情報を確認し、専門家に相談した結果、非常に便利な SQL ステートメントを思いつきました。ここでは、この SQL ステートメントとアイデアを共有します。

需要分析

データベースに重複レコードがある場合は、1つを削除し、1つを残します(重複かどうかを判断する基準は複数のフィールドです)

解決

この要件に遭遇したとき、私はおそらくいくつかのアイデアを思い浮かべていたでしょう。最初に思い浮かぶのは、SQL 文で解決できるのではないかということですが、複雑な SQL 文の経験があまりないので、専門家に助けを求めたいと思っています。

助けてくれる人を見つける

この要件は少し緊急なので、私が最初に考えたのは、この分野の同僚を見つけて解決し、同僚とこの問題を共有することでした。その結果、この人はBaiduを使って、私がこれまで使用したことのないSQLステートメントを提供し、自分で試してみるように頼みました。私の心にはたくさんのことが駆け巡りました...

百度

SQL ステートメントが見つかりました:

消去
から
 ビタミンA
どこ
 (a.peopleId、a.seq) IN (
  選択
   人物ID、
   シーケンス
  から
   履歴書
  グループ化
   人物ID、
   シーケンス
  持つ
   カウント(*) > 1
 )
AND rowid が IN でない (
 選択
  最小(ROWID)
 から
  履歴書
 グループ化
  人物ID、
  シーケンス
 持つ
  カウント(*) > 1
)

この記述は、「MySQL で重複データを削除し、1 つだけ保持する」という記事に記載されています。この SQL ステートメントの考え方は非常に明確で、次の 3 つのステップがあります。

条件としてテーブル内の重複レコードを検索するにはSELECT peopleId, seq FROM vitae GROUP BY peopleId, seq HAVING count(*) > 1

SELECT min(rowid) FROM vitae GROUP BY peopleId, seq HAVING count(*) > 1 2番目の条件として、テーブル内の重複レコードの最小ID値をクエリします。

最後に、上記の2つの条件に従って、重複レコードの最小IDを除く残りの重複レコードを削除します。

しかし残念ながら、このステートメントの実行中にエラーが発生しました。エラーの一般的な意味は、クエリと同時にテーブルを更新できないということです。

コードソリューション

上記の SQL ステートメントに基づいて、コードを通じて 2 つのステップで同じ目的を達成できます。

まず重複したデータセットを削除します

クエリされたデータセットに従って、残っている重複データを削除するループを実行します。

アイデアが浮かんですぐに書き上げたのですが、実行してみると驚きました。約116 秒もかかってしまいました。そこで、使用できる SQL ステートメントを見つけなければならないと考えました。コードと実行結果を投稿しました。

完璧な[重複を削除して1つを残す]SQL

ついに、技術グループから完璧な答えが得られました。次の SQL ステートメントをご覧ください。

消費レコードを削除する
から
 消費レコード、 
 (
  選択
   最小(id) id、
   ユーザーID、
   金銭的、
   消費時間
  から
   消費レコード
  グループ化
   ユーザーID、
   金銭的、
   消費時間
  持つ
   カウント(*) > 1
 ) t2
どこ
 消費レコード.user_id = t2.user_id 
 そしてconsum_record.monetary = t2.monetary
 そして、consum_record.consume_time = t2.consume_time
かつ、consum_record.id > t2.id;

上記の SQL ステートメントを注意深く見ると、その考え方を理解するのは難しくありません。次の 3 つのステップで理解できます。

(SELECT min(id) id, user_id, monetary, consume_time FROM consum_record GROUP BY user_id, monetary, consume_time HAVING count(*) > 1 ) t2

consum_record.user_id = t2.user_id and consum_record.monetary = t2.monetary and consum_record.consume_time = t2.consume_time重複の基準を決定するために使用されるフィールドです

条件に従って、IDがt2のIDより大きい元のテーブルのレコードを削除します。

この文章を見たとき、すごいと思いました。こんなに単純な SQL ステートメントで、こんなに複雑な問題を解決できるなんて、本当に興味深いですね。

実行速度も非常に速いです。元のコードループの実行には約116 秒かかりますが、ここでは0.3 秒しかかかりません。すごいですね。

要約する

PHP プログラマーとして、SQL が遅れをとってはいけないのは当然です。しかし、現実にはやるべきことが多すぎて、現在の私の SQL レベルは平均的なレベルにすぎません。今後、この分野の知識を向上させる機会を見つけたいと思います。

今日はこれで終わりです。

以下もご興味があるかもしれません:
  • MySQL 開発スキル: JOIN 更新とデータ重複チェック/重複排除
  • MySQLデータの重複チェックと重複排除の実装ステートメント
  • MySQLの重複排除方法
  • SQL データベースにおける重複排除についての簡単な説明
  • 重複を削除するSQLグループ化と並べ替えの小さな例
  • MySQL における重複排除の 2 つの方法とサンプル コードの詳細な説明
  • 重複SQLのチェックと削除方法の実践記録

<<:  js は、州、市、地区の 3 段階の選択カスケードを実装します。

>>:  Tomcat が応答データグラムを書き戻すタイミングの詳細な分析

推薦する

シンプルな CSS テキストアニメーション効果

成果を達成する 実装コードhtml <div id=コンテナ> いらっしゃいませ <...

Vue3 でサードパーティのコンポーネントライブラリをオンデマンドでロードする方法

序文Element Plus を例に、コンポーネントとスタイルのオンデマンド読み込みを構成します。環...

HTML チュートリアル: 順序付きリスト

<br />原文: http://andymao.com/andy/post/103.h...

Jenkinsはマイクロサービスをパッケージ化してDockerイメージを構築し、実行します。

目次環境の準備始める1. GitLabリモートリポジトリがマイクロサービスプロジェクトを作成する2....

インラインブロックを使用した複数のdiv間の間隔はプログラミング方法とは異なります

inline-block について学習しているときに、境界線と inline-block を持つ複数...

TypeScript の基本型の紹介

目次1. 基本タイプ2. オブジェクトタイプ2.1 配列2.2 タプル2.3 オブジェクト3. 型推...

大きな MySQL テーブルに列を追加する方法

質問は https://www.zhihu.com/question/440231149 から参照さ...

Centos7 で yum を使用して Ceph 分散ストレージをインストールするチュートリアル

目次序文yumソース、epelソースを設定するCephソースの設定Cephとそのコンポーネントをイン...

Baota LinuxパネルにFTP接続できない問題の解決方法の詳細な説明

Alibaba Cloud Server を使用している場合は、セキュリティ グループ設定でポート ...

Web 標準アプリケーション: Tencent QQ ホームページの再設計

Tencent QQのホームページがリニューアルされ、Webフロントエンド開発がますます注目を集めて...

MySQL の「特殊キーが長すぎます」の解決策

目次解決策1解決策2テーブルを作成するときに、興味深い問題に遭遇しました。「指定されたキーが長すぎま...

Vue のレスポンシブ原則と双方向データの詳細な分析

応答性を実現するための object.defineProperty の理解observe/watch...

フロントエンドアプリケーションのjenkins+gitlab+nginxデプロイメント

目次関連する依存関係のインストールドッカーDockerでJenkinsをインストールするDocker...

nginx パニック問題の解決方法の詳細な説明

nginx パニック問題に関しては、まず nginx の起動プロセス中に、マスター プロセスが構成フ...

CentOS7 で docker を使用して Apollo 構成センターをデプロイする実装

Apollo オープンソース アドレス: https://github.com/ctripcorp/...