溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Oracle如何刪除表中重復記錄

發布時間:2020-08-08 05:00:14 來源:ITPUB博客 閱讀:172 作者:甲OCM_666 欄目:關系型數據庫

Oracle如何刪除表中重復記錄

  引言

在對數據庫進行操作過程中我們可能會遇到這種情況,表中的數據可能重復出現,使我們對數據庫的操作過程中帶來 讀諸 多不便,那么怎么刪除這些重復沒有用的數據呢 ?

平時工作中可能會遇到當試圖對庫表中的某一列或幾列創建唯一索引時,系統提示 ORA-01452  :不能創建唯一索引,發現重復記錄。

  處理過程

重復的數據可能有這樣兩種情況 第一種 表中只有某些字段一樣,第二種是兩行記錄完全一樣 。刪除重復記錄后的結果也分為 2 種, 第一種 是重復的記錄全部刪除 ,第二種是 重復的記錄中只保留最新的一條記錄,一般業務中第二種的情況較多。

 

2.1    刪除重復記錄的方法原理

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

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

 

2.2    刪除部分字段重復數據

2.2.1   重復記錄全部刪除

想要刪除 部分 字段 重復的數據,可以使用下面語句進行刪除 ,下面的語句是刪除 表中字段1 和字段2 重復的數據

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  臨時表 );

這種先建臨時表再進行刪除的操作要比直接用一條語句進行刪除要高效得多。

例子:

Oracle如何刪除表中重復記錄  

   DELETE   FROM  tmp_lhr t

   WHERE    ( t.accesscode ,  t.lastserviceordercode ,  t.serviceinstancecode )   IN

          ( SELECT   a.accesscode ,  a.lastserviceordercode ,  a.serviceinstancecode 

           FROM    tmp_lhr a

           GROUP    BY  a.accesscode ,

                    a.lastserviceordercode ,

                    a.serviceinstancecode

           HAVING   COUNT ( 1 )   >   1 );

Oracle如何刪除表中重復記錄  

 

2.2.2   保留最新的一條記錄

假如 想保留重復數據中最新的一條記錄啊! 那怎么辦呢? 在oracle 中,有個隱藏了自動rowid ,里面給每條記錄一個唯一的rowid ,我們如果想保留最新的一條記錄,我們就可以利用這個字段,保留重復數據中r o wid 最大的一條記錄就可以了。

一、   如何查找重復記錄?

SELECT   *

   FROM  TABLE_NAME  A

  WHERE   ROWID     NOT IN   ( SELECT   MAX ( ROWID )

                    FROM  TABLE_NAME D

                   WHERE   A .COL1  =  D.COL1

                     AND   A .COL2  =  D.COL2 );

二、   如何刪除重復記錄?   1、   方法1

DELETE   FROM  TABLE_NAME

WHERE   ROWID   NOT IN   ( SELECT   MAX ( ROWID )

                    FROM  TABLE_NAME D

                   group   by  d.col1 , d.col2 );

 

這種方法最簡單?。?!

2、   方法2

DELETE   FROM  TABLE_NAME  A

  WHERE   ROWID   NOT IN   ( SELECT   MAX ( ROWID )

                    FROM  TABLE_NAME D

                   WHERE   A .COL1  =  D.COL1

                     AND   A .COL2  =  D.COL2 );

3、   方法3  臨時表

由此,我們要刪除重復數據,只保留最新的一條數據,就可以這樣寫了:

create   table  臨時表  as   select  a.字段1 , a.字段2 , MAX ( a.ROWID )  dataid  from  正式表 a  GROUP   BY  a.字段1 , a.字段2 ;

 

DELETE   FROM   正式 表 a

where  a.rowid  NOT IN   ( SELECT  b.dataid

                        FROM    臨時表 b

                       WHERE   a.字段1  =  b.字段1

    and  a.字段2  =  b.字段2 );

commit ;

 

例子:

   DELETE   FROM  tmp_lhr t

   WHERE   t.rowid  not   in   ( SELECT   MAX ( ROWID )

                      FROM    tmp_lhr a

                      GROUP    BY  a.accesscode ,

                               a.lastserviceordercode ,

                               a.serviceinstancecode );

Oracle如何刪除表中重復記錄  

 

  DELETE   FROM  tmp_lhr t

  WHERE   t.rowid  !=

         ( SELECT   MAX ( ROWID )

          FROM    tmp_lhr a

          WHERE   a.accesscode  =  t.accesscode

          AND     a.lastserviceordercode  =  t.lastserviceordercode

          AND     a.serviceinstancecode  =  t.serviceinstancecode );

Oracle如何刪除表中重復記錄  

 

2.2.3   刪除以某個字段為準的記錄

  ----任意保留一條記錄

DELETE   FROM  ods_entity_info_full_lhr_01 T

WHERE   T.ROWID  NOT   IN   ( SELECT   MAX ( A.ROWID )

                        FROM    ods_entity_info_full_lhr_01 A

                        GROUP    BY  entity_code ,

                                 entity_type );  

         ---保留 entity_id 最大的一條記錄

         DELETE   FROM  ods_entity_info_full_lhr_01 a

         WHERE   a.rowid  NOT   IN

                ( SELECT  t.rowid

                 FROM    ods_entity_info_full_lhr_01 t

                 WHERE    ( t.entity_code ,  t.entity_type ,  t.entity_id )   IN

                        ( SELECT  entity_code ,

                               entity_type ,

                                MAX ( entity_id )

                         FROM    ods_entity_info_full_lhr_01

                         GROUP    BY  entity_code ,

                                  entity_type ));

2.3    刪除完全重復記錄

對于表中兩行記錄完全一樣的情況,可以用下面 三種方式 獲取到去掉重復數據后的記錄:

1.   select   distinct   *   from  表名 ;

2.   select * from  表名  group by  列名 1, 列名 2,... having count(*)>1

3.   select * from   表名  a where rowid<(select max(rowid) from  表名  b where a. 列名 1=b. 列名 2 and ...)

2.3.1   方法 1

   DELETE   FROM  tmp_lhr t

   WHERE   t.rowid  not   in   ( SELECT   MAX ( ROWID )

                      FROM    tmp_lhr a

                      GROUP    BY  a.accesscode ,

                               a.lastserviceordercode ,

                               a.serviceinstancecode );

2.3.2   方法 2

可以將查詢的記錄放到臨時表中,然后再將原來的表記錄刪除,最后將臨時表的數據導回原來的表中。如下:

CREATE   TABLE  臨時表  AS   ( select   distinct   *   from  表名 );

truncate   table  正式表 ;

insert   into  正式表  ( select   *   from  臨時表 );

drop   table  臨時表 ;

 

2.3.3   方法 3

DELETE   FROM  xr_maintainsite E

WHERE   E.ROWID  >   ( SELECT   MIN ( X.ROWID )

                   FROM    xr_maintainsite X

                   WHERE   X.Maintainid  =  E.Maintainid

                   AND     x.siteid  =  e.siteid ); -- 這里被更新表中所有字段都需要寫全

 

2.4    采用row_number 分析函數取出重復的記錄然后刪除序號大于1 的記錄

給出一個例子:

delete from aa where rowid in(select rid from(select rowid rid,row_number() over (partition by name order by id) as seq from aa) where seq>1);

  測試案例

SYS@raclhr1> CREATE TABLE T_ROWS_LHR_20160809 AS SELECT * FROM SCOTT.EMP;

Table created.

SYS@raclhr1> INSERT INTO T_ROWS_LHR_20160809 SELECT * FROM T_ROWS_LHR_20160809;

14 rows created.

SYS@raclhr1> COMMIT;

Commit complete.

SYS@raclhr1> INSERT INTO T_ROWS_LHR_20160809 SELECT * FROM T_ROWS_LHR_20160809;

28 rows created.

SYS@raclhr1> COMMIT;

Commit complete.

SYS@raclhr1> SELECT COUNT(1) FROM T_ROWS_LHR_20160809;

  COUNT(1)

----------

        56

SYS@raclhr1> DELETE FROM T_ROWS_LHR_20160809

  2      WHERE ROWID NOT IN  (SELECT MAX(ROWID)

  3                        FROM T_ROWS_LHR_20160809 D

  4                       group by D.EMPNO,D.ENAME,D.JOB,D.MGR,D.DEPTNO);

42 rows deleted.

SYS@raclhr1> SELECT COUNT(1) FROM T_ROWS_LHR_20160809;

  COUNT(1)

----------

        14

SYS@raclhr1> COMMIT;

Commit complete.

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女