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

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

Oracle中用Rowid查找和刪除重復(fù)記錄

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

  平時(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.

  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用來存放重復(fù)的記錄)

  SQL>truncate table cz; (清空cz表的數(shù)據(jù),但保留cz表的結(jié)構(gòu))

  SQL>insert into cz select * from test;

  (再將臨時(shí)表test里的內(nèi)容反插回來)

  (4).適用于有大量重復(fù)記錄的情況(Exception into 子句法):

  采用alter table 命令中的 Exception into 子句也可以確定出庫(kù)表中重復(fù)的記錄。這種方法稍微麻煩一些,為了使用"excepeion into "子句,必須首先創(chuàng)建 EXCEPTIONS 表。創(chuàng)建該表的 SQL 腳本文件為 utlexcpt.sql 。對(duì)于win2000系統(tǒng)和 UNIX 系統(tǒng), Oracle 存放該文件的位置稍有不同,在win2000系統(tǒng)下,該腳本文件存放在$ORACLE_HOMEOra90rdbmsadmin 目錄下;而對(duì)于 UNIX 系統(tǒng),該腳本文件存放在$ORACLE_HOME/rdbms/admin 目錄下。

  具體步驟如下:

  SQL>@?/rdbms/admin/utlexcpt.sql

  Table created.

  SQL>desc exceptions

  Name Null? Type

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

  ROW_ID ROWID

  OWNER VARCHAR2(30)

  TABLE_NAME VARCHAR2(30)

  CONSTRAINT VARCHAR2(30)

  SQL>alter table cz add constraint

  cz_unique unique(c1,c10,c20) exceptions into exceptions;

  *

  ERROR at line 1:

  ORA-02299: cannot validate (TEST.CZ_UNIQUE) - duplicate keys found

  SQL>create table dups as select

  * from cz where rowid in (select row_id from exceptions);

  Table created.

  SQL>select * from dups;

  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

  16 rows selected.

  SQL>select row_id from exceptions;

  ROW_ID

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

  AAAHD/AAIAAAADSAAA

  AAAHD/AAIAAAADSAAB

  AAAHD/AAIAAAADSAAC

  AAAHD/AAIAAAADSAAF

  AAAHD/AAIAAAADSAAH

  AAAHD/AAIAAAADSAAI

  AAAHD/AAIAAAADSAAG

  AAAHD/AAIAAAADSAAD

  AAAHD/AAIAAAADSAAE

  AAAHD/AAIAAAADSAAJ

  AAAHD/AAIAAAADSAAK

  AAAHD/AAIAAAADSAAL

  AAAHD/AAIAAAADSAAM

  AAAHD/AAIAAAADSAAN

  AAAHD/AAIAAAADSAAO

  AAAHD/AAIAAAADSAAP

  16 rows selected.

  SQL>delete from cz where rowid in

  ( select row_id from exceptions);

  16 rows deleted.

  SQL>insert into cz select distinct * from dups;

  3 rows created.

  SQL>select *from cz;

  C1 C10 C20

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

  1 2 dsf

  2 3 che

  3 4 dff

  4 5 err

  5 3 dar

  6 1 wee

  7 2 zxc

  7 rows selected.

  從結(jié)果里可以看到重復(fù)記錄已經(jīng)刪除。

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

相關(guān)閱讀

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

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