過濾重複數據(eliminate duplicate rows)
在一個數據倉庫項目裏要求對海量數據進行濾重處理。由於沒有主鍵,而且使用的是sql server 2005,沒有oracle裏的rowid字段,我使用了一個臨時表來實現對全字段進行對比,達到過濾重複數據的目的。
初步考慮之後,發現有兩種方法找出重複數據,group by和distinct。但是sql server裏的union | union all | intersect | except,除了 union all 其他都會自動忽視重複數據,所以我沒能這幾個關鍵字想到解決辦法。
下面說的重複記錄是指兩條以上記錄的所有字段完全一致。
方案一,適用於重複率較小的情況。
1、 先把重複記錄寫入臨時表(後綴_duplicate)
INSERT INTO XX_DUPLICATE SELECT * FROM F_XX GROUP BY <ALL COLUMNS> HAVING COUNT(*)>1;
舉例子:
表結構:
create table t1(col1 int, col2 int, col3 char(50))
找出重複數據插入臨時表t1_duplicate,結構和t1一樣。
insert into t1_duplicate select * from t1 group by col1,col2,col3 having count(*) >1
2、 刪除原表中的duplicate rows的記錄。
DELETE F_XX FROM XX_DUPLICATE D left join F_XX F ON <ALL COLUMNS>;
(注意:這裏用的是left join,不是inner join,我的感覺是效率更高一點。)
3、 把臨時表中的記錄插入到原表中,並記錄日誌信息。
INSERT INTO F_XX SELECT * FROM XX_DUPLICATE;
4、 刪除臨時表裏的記錄。
TRUNCATE TABLE XX_DUPLICATE
方案二,適用於重複率較大的情況,雖然不是很常見。主要做法是先把不重複記錄(distinct)放入臨時表,刪除原表的所有數據,在將臨時表的所有數據刷入原表。清空臨時表。