萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 過濾部分欄位重複數據:DISTINCT 不夠用時的 GROUP BY 與自連接刪除法

SELECT DISTINCT 僅能去除完全相同的行,無法針對「某幾個欄位組合重複」保留一條。本文介紹兩類解法:查詢去重(保留首/末行)與物理刪除重複行,並給出標準 SQL 與 MySQL 專用寫法。

場景:username + password 組合去重,保留 ID 最大/最小的行

-- 表結構
ID | username | password | TRDESC
1  | A        | abcdef   | QR
2  | A        | abcdef   | W34
3  | A        | bbbbbb   | AD
4  | B        | aaaaaa   | asdf

保留 ID 最大(最新)

SELECT * FROM mytable 
WHERE ID IN (
  SELECT MAX(ID) FROM mytable GROUP BY username, password
);

保留 ID 最小(最早)

SELECT * FROM mytable 
WHERE ID IN (
  SELECT MIN(ID) FROM mytable GROUP BY username, password
);

通用單欄位去重查詢(相關子查詢)

SELECT * FROM ring_resource AS A
WHERE id = (SELECT MAX(id) FROM ring_resource WHERE name = A.name);

物理刪除重複行(MySQL 專用多表 DELETE)

-- 保留舊記錄(ID 小的)
DELETE FROM a USING test AS a, test AS b 
WHERE a.id > b.id AND a.name = b.name;

-- 保留新記錄(ID 大的)
DELETE FROM a USING test AS a, test AS b 
WHERE a.id < b.id AND a.name = b.name;

驗證結果

原表:

idname
1test
2demo
3test

執行「保留舊記錄」刪除後:

idname
1test
2demo

id=3 的重複 test 被移除。

效能與注意事項

  • 大表刪除:分批次(如每次 1 萬行)避免長事務鎖表、Binlog 膨脹。
  • 索引支撐:去重欄位(name)+ id 建立組合索引 (name, id) 加速自連接。
  • 事務包裹:生產環境務必 START TRANSACTION; ... COMMIT; 並先 SELECT 驗證影響行數。
  • 備份優先:刪除不可逆,先 CREATE TABLE backup AS SELECT * FROM test;。

總結選型

需求推薦寫法
僅查詢不重複SELECT ... WHERE id IN (SELECT MAX(id) ... GROUP BY col)
永久刪除重複DELETE FROM a USING t a, t b WHERE a.id > b.id AND a.col = b.col
保留最新/最早調整 MAX/MIN 或 >/< 方向
多欄位組合去重GROUP BY col1, col2, col3

掌握 GROUP BY + 聚合 與 多表 DELETE 兩大核心模式,即可應對 90% 以上的部分欄位去重場景。

copyright © 萬盛學電腦網 all rights reserved