很多人新手對於數據庫distinct 的用法有誤解接下來我們看一段代碼:
數據表:table id name
1 a
2 b
3 c
4 c
5 b
我們使用distinct來去重name是這樣:
select distinct name from table 結果為:
a
b
c
可是一般數據庫去重都是需要不止一個字段接下來看這個:
select distinct name, id from table 多了個id效果會怎樣呢
1 a
2 b
3 c
4 c
5 b
結果並不是我們想象的一樣去重了接下來我們繼續:
select *, count(distinct name) from table group by name 這條sql 就不一樣了效果如下
1 a 1
2 b 1
3 c 1
看到效果了吧,只是后面多了一個count 查出來的數據這個不影響,是可以用的.
2.Sql去重語句
海量數據(百萬以上),其中有些全部字段都相同,有些部分字段相同,怎樣高效去除重復?
如果要刪除手機(mobilePhone),電話(officePhone),郵件(email)同時都相同的數據,以前一直使用這條語句進行去重:
1 |
delete from 表 where id not in |
2 |
( select max (id) from 表 group by mobilePhone,officePhone,email ) |
3 |
or |
4 |
delete from 表 where id not in |
5 |
( select min (id) from 表 group by mobilePhone,officePhone,email ) |
其中下面這條會稍快些。上面這條數據對於100萬以內的數據效率還可以,重復數1/5的情況下幾分鍾到幾十分鍾不等,但是如果數據量達到300萬以上,效率驟降,如果重復數據再多點的話,常常會幾十小時跑不完,有時候會鎖表跑一夜都跑不完。無奈只得重新尋找新的可行方法,今天終於有所收獲:
1 |
//查詢出唯一數據的ID,並把他們導入臨時表tmp中 |
2 |
select min (id) as mid into tmp from 表 group by mobilePhone,officePhone,email |
3 |
4 |
//查詢出去重后的數據並插入finally表中 |
5 |
insert into finally select (除ID以外的字段) from customers_1 where id in ( select mid from tmp) |
效率對比:用delete方法對500萬數據去重(1/2重復)約4小時。4小時,很長的時間。
用臨時表插入對500萬數據去重(1/2重復)不到10分鍾。
SQL語句去掉重復記錄,獲取重復記錄
按照某幾個字段名稱查找表中存在這幾個字段的重復數據並按照插入的時間先后進行刪除,條件取決於order by 和row_num。
方法一按照多條件重復處理:
|
delete tmp from ( |
|
select row_num = row_number() over(partition by 字段,字段 order by 時間 desc ) |
|
from 表 where 時間> getdate()-1 |
|
) tmp |
|
where row_num > 1 |
方法二按照單一條件進行去重:
|
delete from 表 where 主鍵ID not in( |
|
select max(主鍵ID) from 表 group by 需要去重的字段 having count (需要去重的字段)>=1 |
|
) |
注意:為提高效率如上兩個方法都可以使用臨時表, not in 中的表可以先提取臨時表#tmp,
然后采用not exists來執行,為避免數量過大,可批量用Top控制刪除量
|
delete top (2) from 表 |
|
where not exists ( select 主鍵ID |
sql 去重具體方式就先寫這一種,第二種博客看到的,后期待續.各位大神別噴.
Sql去重語句
海量數據(百萬以上),其中有些全部字段都相同,有些部分字段相同,怎樣高效去除重復?
如果要刪除手機(mobilePhone),電話(officePhone),郵件(email)同時都相同的數據,以前一直使用這條語句進行去重:
|
delete from 表 where id not in |
|
( select max (id) from 表 group by mobilePhone,officePhone,email ) |
|
or |
|
delete from 表 where id not in |
|
( select min (id) from 表 group by mobilePhone,officePhone,email ) |
其中下面這條會稍快些。上面這條數據對於100萬以內的數據效率還可以,重復數1/5的情況下幾分鍾到幾十分鍾不等,但是如果數據量達到300萬以上,效率驟降,如果重復數據再多點的話,常常會幾十小時跑不完,有時候會鎖表跑一夜都跑不完。無奈只得重新尋找新的可行方法,今天終於有所收獲:
|
//查詢出唯一數據的ID,並把他們導入臨時表tmp中 |
|
select min (id) as mid into tmp from 表 group by mobilePhone,officePhone,email |
|
//查詢出去重后的數據並插入finally表中 |
|
insert into finally select (除ID以外的字段) from customers_1 where id in ( select mid from tmp) |
效率對比:用delete方法對500萬數據去重(1/2重復)約4小時。4小時,很長的時間。
用臨時表插入對500萬數據去重(1/2重復)不到10分鍾。
SQL語句去掉重復記錄,獲取重復記錄
按照某幾個字段名稱查找表中存在這幾個字段的重復數據並按照插入的時間先后進行刪除,條件取決於order by 和row_num。
方法一按照多條件重復處理:
|
delete tmp from ( |
|
select row_num = row_number() over(partition by 字段,字段 order by 時間 desc ) |
|
from 表 where 時間> getdate()-1 |
|
) tmp |
|
where row_num > 1 |
方法二按照單一條件進行去重:
|
delete from 表 where 主鍵ID not in( |
|
select max(主鍵ID) from 表 group by 需要去重的字段 having count (需要去重的字段)>=1 |
|
) |
注意:為提高效率如上兩個方法都可以使用臨時表, not in 中的表可以先提取臨時表#tmp,
然后采用not exists來執行,為避免數量過大,可批量用Top控制刪除量
|
delete top (2) from 表 |
|
where not exists ( select 主鍵ID |