爲了對重複數據進行實驗,下面建一個設計不太好(沒有主鍵)表並插入了一些重複數據:sql
create database testdb use testdb ; go create table DupsNoPK (Col1 int Null, Col2 char(5) Null ); go insert DupsNoPK(Col1,Col2) Values(1,'abc'), (2,'abc'), (2,'abc'), (2,'abc'), (7,'xyz'), (7,'xyz');
爲了驗證表確實有重複數據,下面查詢運用了一個group by 和having 子句只返回重複行,並對副本計數:函數
select Col1,Col2,Count(*) AS DupCount from DupsNoPK group by Col1,Col2 having count(*)>1;
結果:測試
下面是運用窗口化刪除重複行:設計
這種方法的關鍵是運用窗口化的,有row_number()函數和分區的over()子句。每一個新分區會從新編號。設置over()子句爲partition by每一個要檢查重複數據的列。在這種狀況下每一列都會進行檢查。blog
運行窗口化查詢,首先顯示方法如何應用於行號:it
select Col1,Col2, row_number()over(partition by Col1,Col2 order by Col1)as rn from DupsNoPK
結果:io
每個重複行都有一個比1大的rn值,因此,刪除副本是比較容易的:table
with DupsNumbered as( select Col1,Col2, row_number()over(partition by Col1,Col2 order by Col1) as rn from DupsNoPK ) delete DupsNumbered where rn>1;
結果:class
執行完上面語句後,下面用一條select語句測試刪除重複數據的結果:test