SELECT DISTINCT 僅能去除完全相同的行,無法針對「某幾個欄位組合重複」保留一條。本文介紹兩類解法:查詢去重(保留首/末行)與物理刪除重複行,並給出標準 SQL 與 MySQL 專用寫法。
-- 表結構 ID | username | password | TRDESC 1 | A | abcdef | QR 2 | A | abcdef | W34 3 | A | bbbbbb | AD 4 | B | aaaaaa | asdf
SELECT * FROM mytable WHERE ID IN ( SELECT MAX(ID) FROM mytable GROUP BY username, password );
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);
-- 保留舊記錄(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;
原表:
| id | name |
|---|---|
| 1 | test |
| 2 | demo |
| 3 | test |
執行「保留舊記錄」刪除後:
| id | name |
|---|---|
| 1 | test |
| 2 | demo |
id=3 的重複 test 被移除。
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% 以上的部分欄位去重場景。