IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類(lèi)|軟件專(zhuān)題|手機(jī)版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當(dāng)前所在位置: 首頁(yè)數(shù)據(jù)庫(kù)Oracle → oracle 查找、刪除重復(fù)記錄

oracle 查找、刪除重復(fù)記錄

時(shí)間:2015-06-28 00:00:00 來(lái)源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(12)

  總結(jié)了一下刪除重復(fù)記錄的方法,以及每種方法的優(yōu)缺點(diǎn)。

  假設(shè)表名為T(mén)bl,表中有三列col1,col2,col3,其中col1,col2是主鍵,并且,col1,col2上加了索引。

  1、通過(guò)創(chuàng)建臨時(shí)表

  可以把數(shù)據(jù)先導(dǎo)入到一個(gè)臨時(shí)表中,然后刪除原表的數(shù)據(jù),再把數(shù)據(jù)導(dǎo)回原表,SQL語(yǔ)句如下:

  creat table tbl_tmp (select distinct* from tbl);

  truncate table tbl;//清空表記錄

  insert into tbl select * from tbl_tmp;//將臨時(shí)表中的數(shù)據(jù)插回來(lái)。

  這種方法可以實(shí)現(xiàn)需求,但是很明顯,對(duì)于一個(gè)千萬(wàn)級(jí)記錄的表,這種方法很慢,在生產(chǎn)系統(tǒng)中,這會(huì)給系統(tǒng)帶來(lái)很大的開(kāi)銷(xiāo),不可行。

  2、利用rowid

  在oracle中,每一條記錄都有一個(gè)rowid,rowid在整個(gè)數(shù)據(jù)庫(kù)中是唯一的,rowid確定了每條記錄是oracle中的哪一個(gè)數(shù)據(jù)文件、塊、行上。在重復(fù)的記錄中,可能所有列的內(nèi)容都相同,但rowid不會(huì)相同。SQL語(yǔ)句如下:

  delete from tbl where rowid in (select a.rowid from tbl a, tbl b where a.rowid>b.rowid and a.col1=b.col1 and a.col2 = b.col2)

  如果已經(jīng)知道每條記錄只有一條重復(fù)的,這個(gè)sql語(yǔ)句適用。但是如果每條記錄的重復(fù)記錄有N條,這個(gè)N是未知的,就要考慮適用下面這種方法了。

  3、利用max或min函數(shù)

  這里也要使用rowid,與上面不同的是結(jié)合max或min函數(shù)來(lái)實(shí)現(xiàn)。SQL語(yǔ)句如下

  delete from tbl a where rowid not in (select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2);//這里max使用min也可以

  或者用下面的語(yǔ)句

  delete from tbl a where rowid < (select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2

  4、利用group by,提高效率

  平時(shí)工作中可能會(huì)遇到當(dāng)試圖對(duì)庫(kù)表中的某一列或幾列創(chuàng)建唯一索引時(shí),系統(tǒng)提示 ORA-01452 :不能創(chuàng)建唯一索引,發(fā)現(xiàn)重復(fù)記錄。

  下面總結(jié)一下幾種查找和刪除重復(fù)記錄的方法(以表CZ為例):

  表CZ的結(jié)構(gòu)如下:

  SQL> desc cz

  Name? Null???? Type

  ----------------------------------------- -------- ------------------

  C1 NUMBER(10)

  C10????? NUMBER(5)

  C20????? VARCHAR2(3)

  刪除重復(fù)記錄的方法原理:

  (1).在Oracle中,每一條記錄都有一個(gè)rowid,rowid在整個(gè)數(shù)據(jù)庫(kù)中是唯一的,rowid確定了每條記錄是在Oracle中的哪一個(gè)數(shù)據(jù)文件、塊、行上。

  (2).在重復(fù)的記錄中,可能所有列的內(nèi)容都相同,但rowid不會(huì)相同,所以只要確定出重復(fù)記錄中那些具有最大rowid的就可以了,其余全部刪除。

  重復(fù)記錄判斷的標(biāo)準(zhǔn)是:

  C1,C10和C20這三列的值都相同才算是重復(fù)記錄。

  經(jīng)查看表CZ總共有16條記錄:

  SQL>set pagesize 100

  SQL>select * from cz;

  C1? C10 C20

  ---------- ---------- ---

  1??? 2??? dsf

  1??? 2??? dsf

  1??? 2?? dsf

  1??? 2?? dsf

  2??? 3?? che

  1??? 2?? dsf

  1??? 2?? dsf

  1??? 2?? dsf

  1??? 2?? dsf

  2??? 3?? che

  2??? 3?? che

  2??? 3?? che

  2??? 3?? che

  3??? 4?? dff

  3??? 4?? dff

  3??? 4?? dff

  4??? 5?? err

  5??? 3?? dar

  6??? 1?? wee

  7??? 2?? zxc

  20 rows selected.

#p#副標(biāo)題#e#

  1.查找重復(fù)記錄的幾種方法:

  (1).SQL>select * from cz group by c1,c10,c20 having count(*) >1;

  C1? C10 C20

  ---------- ---------- ---

  1??? 2?? dsf

  2??? 3?? che

  3??? 4?? dff

  (2).SQL>select distinct * from cz;

  C1? C10 C20

  ---------- ---------- ---

  1??? 2?? dsf

  2??? 3?? che

  3??? 4?? dff

  (3).SQL>select * from cz a where rowid=(select max(rowid) from cz where c1=a.c1 and c10=a.c10 and c20=a.c20);

  C1? C10 C20

  ---------- ---------- ---

  1??? 2?? dsf

  2??? 3?? che

  3??? 4?? dff

  2.刪除重復(fù)記錄的幾種方法:

  (1).適用于有大量重復(fù)記錄的情況(在C1,C10和C20列上建有索引的時(shí)候,用以下語(yǔ)句效率會(huì)很高):

  SQL>delete cz where (c1,c10,c20) in (select c1,c10,c20 from cz group by c1,c10,c20 having count(*)>1) and rowid not in

  (select min(rowid) from cz group by c1,c10,c20 having count(*)>1);

  SQL>delete cz where rowid not in(select min(rowid) from cz group by c1,c10,c20);

  (2).適用于有少量重復(fù)記錄的情況(注意,對(duì)于有大量重復(fù)記錄的情況,用以下語(yǔ)句效率會(huì)很低):

  SQL>delete from cz a where a.rowid!=(select max(rowid) from cz b where a.c1=b.c1 and a.c10=b.c10 and a.c20=b.c20);

  SQL>delete from cz a where a.rowid<(select max(rowid) from cz b where a.c1=b.c1 and a.c10=b.c10 and a.c20=b.c20);

  SQL>delete from cz a where rowid <(select max(rowid) from cz where c1=a.c1 and c10=a.c10 and c20=a.c20);

  (3).適用于有少量重復(fù)記錄的情況(臨時(shí)表法):

  SQL>create table test as select distinct * from cz; (建一個(gè)臨時(shí)表test用來(lái)存放重復(fù)的記錄)

 

關(guān)鍵詞標(biāo)簽:oracle

相關(guān)閱讀

文章評(píng)論
發(fā)表評(píng)論

熱門(mén)文章 Oracle中使用alter table來(lái)增加,刪除,修改列的語(yǔ)法 Oracle中使用alter table來(lái)增加,刪除,修改列的語(yǔ)法 oracle中使用SQL語(yǔ)句修改字段類(lèi)型-oracle修改SQL語(yǔ)句案例 oracle中使用SQL語(yǔ)句修改字段類(lèi)型-oracle修改SQL語(yǔ)句案例 誤刪Oracle數(shù)據(jù)庫(kù)實(shí)例的控制文件 誤刪Oracle數(shù)據(jù)庫(kù)實(shí)例的控制文件 為UNIX服務(wù)器設(shè)置Oracle全文檢索 為UNIX服務(wù)器設(shè)置Oracle全文檢索

相關(guān)下載

    人氣排行 oracle中使用SQL語(yǔ)句修改字段類(lèi)型-oracle修改SQL語(yǔ)句案例 Oracle中使用alter table來(lái)增加,刪除,修改列的語(yǔ)法 ORACLE SQL 判斷字符串是否為數(shù)字的語(yǔ)句 ORACLE和SQL語(yǔ)法區(qū)別歸納(1) oracle grant 授權(quán)語(yǔ)句 ORACLE修改IP地址后如何能夠使用 如何加速Oracle大批量數(shù)據(jù)處理 Oracle刪除表的幾種方法