mysql重複データを削除id最大のデータのみを保持

4592 ワード

前言
今日、データベース内のフィールド(source_id)の重複データを削除する必要がありますが、そのフィールドのパケットに基づいて、パケットの最大の1つを取得し、not inでラップし、delete文を実行することを考えています.途中で2つの問題に遭遇しました.1つ目はMySql]You can't specify target table for update in FROM clauseを間違えました.ブログを参考にしてください.https://blog.csdn.net/jsloveyou/article/details/79024600解決しました.2つ目の問題は、私が書いたsqlは複雑で、大物の指摘を経て最終的に以下のように実現しました.
最終的に実装されたsql
DELETE
FROM
	draft_video
WHERE
	draft_video.id NOT IN (
		SELECT
			result.id
		FROM
			(
				SELECT
					max(d.id) AS id
				FROM
					draft_video d
				GROUP BY
					source_id
			) AS result
	)

途中で出会った問題
質問1:エラーメッセージ:MySql]You can’t specify target table for update in FROM clause
理由:MySQLがデータを変更または削除する際に、現在のテーブルをfrom条件とすることはできません.ソリューションリファレンス:https://blog.csdn.net/jsloveyou/article/details/79024600
問題2:複雑なsql実装
実現思想:
  • source_によるとidパケット、having count(source_id)>1のデータ、すなわちデータベース内の重複データ
  • である.
  • クエリーに基づいてsource_を出力idに重複するsourceIdにおけるid最大のデータ取り出し
  • 1 1,2のデータをand接続クエリーし、最終的に結果
  • を取得する.
    DELETE
    FROM
    	draft_video
    WHERE
    	draft_video.source_id IN (
    		SELECT
    			r1.source_id
    		FROM
    			(
    				SELECT
    					source_id
    				FROM
    					draft_video
    				GROUP BY
    					source_id
    				HAVING
    					COUNT(source_id) > 1
    			) AS r1
    	)
    AND draft_video.id NOT IN (
    	SELECT
    		r2.id
    	FROM
    		(
    			SELECT
    				MAX(draft_video.id) as id
    			FROM
    				draft_video
    			GROUP BY
    				draft_video.source_id
    			HAVING
    				COUNT(draft_video.source_id) > 1
    		) AS r2
    );
    

    この実装方式は比較的肥大化しており,性能が悪いことがわかる.
    大物のリクエスト
    私は高級java技術共有グループ(821605718、私はグループの主人)でこのsqlを共有した後、ある大物が最終的にsqlを得て、私に逆思考でこの問題を処理するように指導しました.男の原話は以下の通りです.
    重複していない場合はgroupbyの後に最大のIDを持つのは自分のものではないでしょうか.重複したグループがある後、最大のIDを持つのはあなたが残すものではないでしょうか.
    三人行には必ず私の師焉があります.みんなが勉強したい友达が一緒に問題を検討することを歓迎します.