為了對重復數據進行實驗,下面建一個設計不太好(沒有主鍵)表并插入了一些重復數據:
create database testdbuse testdb ;gocreate table DupsNoPK(Col1 int Null, Col2 char(5) Null);goinsert DupsNoPK(Col1,Col2)Values(1,'abc'), (2,'abc'), (2,'abc'), (2,'abc'), (7,'xyz'), (7,'xyz');
為了驗證表確實有重復數據,下面查詢運用了一個group by 和having 子句只返回重復行,并對副本計數:
select Col1,Col2,Count(*) AS DupCountfrom DupsNoPKgroup by Col1,Col2having count(*)>1;
結果:
下面是運用窗口化刪除重復行:
這種方法的關鍵是運用窗口化的,有row_number()函數和分區的over()子句。每個新分區會重新編號。設置over()子句為partition by每個要檢查重復數據的列。在這種情況下每一列都會進行檢查。
運行窗口化查詢,首先顯示方法如何應用于行號:
select Col1,Col2, row_number()over(partition by Col1,Col2 order by Col1)as rn from DupsNoPK
結果:
每一個重復行都有一個比1大的rn值,所以,刪除副本是比較容易的:
with DupsNumberedas( select Col1,Col2, row_number()over(partition by Col1,Col2 order by Col1) as rn from DupsNoPK )delete DupsNumbered where rn>1;
結果:
執行完上面語句后,下面用一條select語句測試刪除重復數據的結果:
新聞熱點
疑難解答