【初級】有極少的重復行
使用distinct查出來,然后手動一行一行刪除。
【中級】按照單個字段的重復去重
例如:對id字段去重
使用方法:獲取id的重復字段的值,利用相同id字段所在的行中,比較出數據不同的字段,刪除 除了最?。ɑ蜃畲螅┑淖侄嗡诘脑撔兄獾乃兄貜偷男?。一般使用主鍵來比較,因為主鍵的值一定是唯一值,絕對不相同。
1
2
3
4
5
6
7
8
9
10
11
|
id name 1 a 1 b 2 c 2 a 3 c |
結果:
1
2
3
4
5
|
id name 1 a 2 a |
操作:
1
2
3
4
5
|
delete from a_tmp where id in ( select * from ( select b.id from a_tmp b group by b.id having count (b.id) >1) bb) and name not in ( select * from ( select min (a. name ) from a_tmp a GROUP BY a.id having count (a.id) >1) aa); |
注意:
上述加粗并綠色的字,必須加別名,必須使用select * from (……)這樣的格式,否則會報錯:
[Err] 1093 - You can't specify target table 'a_tmp' for update in FROM clause
【高級】按多個字段的重復來去重
例如:對id,name相同的去重,即:對id,name都相同的算作重復行,對id相同而name不同的算作不重復行
使用方法:和單個字段相似,一般使用主鍵來比較,因為主鍵的值一定是唯一值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
id name rowid 1 a 1 1 a 2 1 b 3 2 b 4 2 b 5 3 c 6 3 d 7 |
結果:
1
2
3
4
5
6
7
8
9
10
11
|
id name rowid 1 a 1 1 b 3 2 b 4 3 c 6 3 d 7 |
操作:
第一種:
1
2
3
4
5
|
delete from a_tmp where (id, name ) in ( select * from ( select b.id,b. name from a_tmp b group by b.id,b. name having count (b.id) >1) bb) and rowid not in ( select * from ( select min (a.rowid) from a_tmp a group by a.id,a. name having count (a.id) >1) aa); |
第二種:
將id和name字段的值連接起來插入到臨時表中b_tmp,這樣便可以使用【中級】的單字段的判斷刪除方法。
#將兩字段連接的值,a_tmp表中唯一值的字段插入b_tmp表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
insert into b_tmp select concat(id, name ),rowid from a_tmp; #查出需要留下來的行 select id_name, max (rowid) from b_tmp group by id_name having count (id_name)>1; #使用【中級】的方法,或存儲過程完成去重的工作 |
【終極】每行都有兩份一樣的數據
例如:
使用方法:對于整行的數據都一樣,是沒辦法使用SQL語句刪除的,因為沒有可以使用的條件限制來留下一行刪除所有與其相同的行。沒有不同的字段可以自己創造不同的字段,即:添加一個字段,設為自增長,并設為主鍵,它會自動添加上值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
id name 1 a 1 a 1 b 1 b 2 c 2 c 3 c 3 c |
結果:
1
2
3
4
5
6
7
8
9
|
id name rowid 1 a 1 1 b 3 2 c 5 3 c 7 |
操作:
添加一個自增長的字段,并暫時設為主鍵。
使用上面【中級】和【高級】的方法操作。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:https://my.oschina.net/starglm/blog/748701