1 引言
在對數據庫進行操作過程中我們可能會遇到這種情況,表中的數據可能重復出現,使我們對數據庫的操作過程中帶來讀諸多不便,那么怎么刪除這些重復沒有用的數據呢?
平時工作中可能會遇到當試圖對庫表中的某一列或幾列創建唯一索引時,系統提示 ORA-01452 :不能創建唯一索引,發現重復記錄。
2 處理過程
重復的數據可能有這樣兩種情況:第一種是表中只有某些字段一樣,第二種是兩行記錄完全一樣。刪除重復記錄后的結果也分為2種,第一種是重復的記錄全部刪除,第二種是重復的記錄中只保留最新的一條記錄,一般業務中第二種的情況較多。
2.1 刪除重復記錄的方法原理
(1)在Oracle中,每一條記錄都有一個rowid,rowid在整個數據庫中是唯一的,rowid確定了每條記錄是在Oracle中的哪一個數據文件、塊、行上。
(2)在重復的記錄中,可能所有列的內容都相同,但rowid不會相同,所以只要確定出重復記錄中那些具有最大rowid的就可以了,其余全部刪除。
2.2 刪除部分字段重復數據
2.2.1 重復記錄全部刪除
DELETE FROM 表名 a WHERE (字段1, 字段2) IN (SELECT 字段1,字段2 FROM 表名 GROUP BY 字段1,字段2 HAVING COUNT(1) > 1);
---上面的語句非常簡單,就是將查詢到的數據刪除掉。不過這種刪除執行的效率非常低,對於大數據量來說,可能會將數據庫吊死。所以建議先將查詢到的重復的數據插入到一個臨時表中,然后進行刪除,
這樣,執行刪除的時候就不用再進行一次查詢了。如下: 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.2.2 保留最新的一條記錄
假如想保留重復數據中最新的一條記錄啊!那怎么辦呢?在oracle中,有個隱藏了自動rowid,里面給每條記錄一個唯一的rowid,我們如果想保留最新的一條記錄,我們就可以利用這個字段,保留重復數據中rowid
最大的一條記錄就可以了。 一、 如何查找重復記錄? SELECT * FROM bcm.table1 A WHERE ROWID NOT IN (SELECT MAX(ROWID) FROM bcm.table1 D WHERE A.id= D.id and ...);
select distinct * from 表名;
select name,Count(name) from user group by name having Count(name) >1
二、 如何刪除重復記錄?
刪除相同的數據,保留最大的id或者最小的id min(id)
delete from user where id not in(select max(id) from user group by name) ---這種方法最簡單!!!
---臨時表
由此,我們要刪除重復數據,只保留最新的一條數據,就可以這樣寫了:
create table t_rows_tmp as select D.EMPNO,D.ENAME,D.JOB,D.MGR,D.DEPTNO,MAX(a.ROWID) dataid from T_ROWS a GROUP BY D.EMPNO,D.ENAME,D.JOB,D.MGR,D.DEPTNO;
DELETE FROM T_ROWS a where a.rowid NOT IN (SELECT b.dataid FROM t_rows_tmp b WHERE a.EMPNO = b.EMPNO and a.DEPTNO = b.DEPTNO);
commit;
舉例:
select count(*) from test2020; create table test2020_bak as select * from test2020; select count(*) from test2020_bak; select count(*) from test2020 a where rowid !=(select max(rowid) from test2020 b where a.OBJECT_ID=b.OBJECT_ID ); ---使用rowid查詢重復數據記錄數 delete from test2020 a where rowid !=(select max(rowid) from test2020 b where a.object_id=b.object_id) ---刪除重復數據
alter table test2020 add constraint pk_obj_id primary key (object_id);