oracle重複資料的查詢及刪除

dawn009發表於2014-03-03
----&gt>轉載於:
重複的資料可能有這樣兩種情況,第一種: 表中只有某些欄位一樣,第二種是兩行記錄完全一樣。 

一、對於部分欄位重複資料的刪除 
1.查詢重複的資料   
select 欄位1,欄位2, count(*) from 表名 group by 欄位1,欄位2 having count(*) > 1    
例:Select owner from dba_tables group by owner having count(*)>1; 
Select owner from dba_tables group by owner having count(*)=1; //查詢出沒有重複的資料   
2.刪除重複的資料 
delete from 表名 a where 欄位1,欄位2 in (select 欄位1,欄位2,count(*) from 表名 group by 欄位1,欄位2 having count(*) > 1) 
這種刪除執行的效率非常低,對於大資料量來說,可能會將資料庫吊死。 
另一種高效率的方法是先將查詢到的重複的資料插入到一個臨時表中,然後再進行刪除。 
CREATE TABLE 臨時表 AS 

select 欄位1,欄位2, count(*) as row_num 
from 表名 
group by 欄位1,欄位2 
having count(*) > 1 
); 
  上面這句話就是建立了臨時表,並將查詢到的資料插入其中。 
  下面就可以進行這樣的刪除操作了: 
delete from 表名 a 
where 欄位1,欄位2 in (select 欄位1,欄位2 from 臨時表);    
3.保留重複資料中最新的一條記錄 
在Oracle中,rowid是隱藏欄位,用來唯一標識每條記錄。所以,只要保留重複資料中rowid最大的一條記錄就可以了。   
查詢重複資料: 
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 );    
例:selete from dba_tables a 
where a.rowid!=( 
select max(rowid) from test b 
where a.owner=b.owner); 
  刪除重複資料,只保留最新的一條資料: 
delete from 表名 a 
where a.rowid != ( 
select max(b.rowid) from 表名 b 
where a.欄位1 = b.欄位1 and a.欄位2 = b.欄位2 ) 
  使用臨時表實現高效查詢 
create table 臨時表 as 
(select a.欄位1, a.欄位2, MAX(a.ROWID) as 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; 
  二、對於完全重複記錄的刪除 
  對於表中兩行記錄完全一樣的情況,可以用下面語句獲取到去掉重複資料後的記錄: 
select distinct * from 表名 
可以將查詢的記錄放到臨時表中,然後再將原來的表記錄刪除,最後將臨時表的資料導回原來的表中。如下: 
CREATE TABLE 臨時表 AS (select distinct * from 表名); 
drop table 正式表; 
insert into 正式表 (select * from 臨時表); 
drop table 臨時表;   假如想刪除一個表的重複資料,可以先建一個臨時表,將去掉重複資料後的資料匯入到臨時表,然後在從臨時表將資料匯入正式表中,如下: INSERT INTO t_table_bak 
select distinct * from t_table;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29119536/viewspace-1098766/,如需轉載,請註明出處,否則將追究法律責任。

相關文章