問(wèn)題描述:
如何刪除數(shù)據(jù)庫(kù)中的重復(fù)數(shù)據(jù)
問(wèn)題原因:
某些時(shí)候,數(shù)據(jù)庫(kù)中需要添加新的唯一性約束,但是數(shù)據(jù)庫(kù)中已經(jīng)存在了重復(fù)的數(shù)據(jù),此時(shí)需要?jiǎng)h除重復(fù)的數(shù)據(jù)
解決方法:
查詢重復(fù)的數(shù)據(jù):
select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1
備注:將上面的>號(hào)改為=號(hào)就可以查詢出沒(méi)有重復(fù)的數(shù)據(jù)了。
(1)Oracle刪除重復(fù)數(shù)據(jù)的SQL(刪除所有,重復(fù)的一個(gè)都不留)刪除重復(fù)數(shù)據(jù)的基本結(jié)構(gòu)寫(xiě)法:
delete from 表名 a where 字段1,字段2 in
(select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)
不過(guò)這種刪除執(zhí)行的效率非常低,建議先將查詢到的重復(fù)的數(shù)據(jù)插入到一個(gè)臨時(shí)表中,然后對(duì)進(jìn)行刪除,這樣,執(zhí)行刪除的時(shí)候就不用再進(jìn)行一次查詢了。如下:
CREATE TABLE 臨時(shí)表 AS (select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)
delete from 表名 a where 字段1,字段2 in (select 字段1,字段2 from 臨時(shí)表);
(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 )
括號(hào)中的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 )
當(dāng)然,上面語(yǔ)句的執(zhí)行效率是很低的,可以考慮建立臨時(shí)表,講需要判斷重復(fù)的字段、rowid插入臨時(shí)表中,然后刪除的時(shí)候在進(jìn)行比較。
create table 臨時(shí)表 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 臨時(shí)表 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)險(xiǎn),搞事以前
先備份
create table 備份表 as select * from 原表;