問題描述:
如何刪除數(shù)據(jù)庫中的重復(fù)數(shù)據(jù)
問題原因:
某些時候,數(shù)據(jù)庫中需要添加新的唯一性約束,但是數(shù)據(jù)庫中已經(jīng)存在了重復(fù)的數(shù)據(jù)橘洞,此時需要刪除重復(fù)的數(shù)據(jù)
解決方法:
查詢重復(fù)的數(shù)據(jù):
select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1
備注:將上面的>號改為=號就可以查詢出沒有重復(fù)的數(shù)據(jù)了夹孔。
(1)Oracle刪除重復(fù)數(shù)據(jù)的SQL(刪除所有,重復(fù)的一個都不留)刪除重復(fù)數(shù)據(jù)的基本結(jié)構(gòu)寫法:
delete from 表名 a where 字段1,字段2 in
(select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)
不過這種刪除執(zhí)行的效率非常低琅轧,建議先將查詢到的重復(fù)的數(shù)據(jù)插入到一個臨時表中伍绳,然后對進行刪除,這樣乍桂,執(zhí)行刪除的時候就不用再進行一次查詢了冲杀。如下:
CREATE TABLE 臨時表 AS (select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)
delete from 表名 a where 字段1,字段2 in (select 字段1,字段2 from 臨時表);
(2)刪除重復(fù)數(shù)據(jù)的SQL(重復(fù)的留下一條記錄)使用ROWID查詢重復(fù)數(shù)據(jù):
select a.rowid,a.* from 表名 a where a.rowid !=
(select max(b.rowid) from 表名 b where a.字段1 = b.字段1 and a.字段2 = b.字段2 )
括號中的SQL查詢出rowid最大的記錄睹酌,而外面就是查詢出除了rowid最大之外的其他重復(fù)的數(shù)據(jù)了权谁。
刪除重復(fù)數(shù)據(jù)(留下最大ROWID的一條)
delete from 表名 a where a.rowid !=
(select max(b.rowid) from 表名 b where a.字段1 = b.字段1 and a.字段2 = b.字段2 )
當然,上面語句的執(zhí)行效率是很低的忍疾,可以考慮建立臨時表闯传,講需要判斷重復(fù)的字段、rowid插入臨時表中卤妒,然后刪除的時候在進行比較甥绿。
create table 臨時表 as select a.字段1,a.字段2,MAX(a.ROWID) dataid from 正式表 a GROUP BY a.字段1,a.字段2;
delete from 表名 a where a.rowid !=
(select b.dataid from 臨時表 b where a.字段1 = b.字段1 and a.字段2 = b.字段2 );
commit;
以列形式刪除重復(fù)數(shù)據(jù)
delete from test1 where a in (select a from test1 group by a having count(a) > 1)
刪除操作有風(fēng)險,搞事以前
先備份
create table 備份表 as select * from 原表;