oracle快速刪除重復的記錄
更新時間:2007年03月07日 00:00:00 作者:
正在看的ORACLE教程是:oracle快速刪除重復的記錄。做項目的時候,一位同事導數(shù)據(jù)的時候,不小心把一個表中的數(shù)據(jù)全都搞重了,也就是說,這個表里所有的記錄都有一條重復的。這個表的數(shù)據(jù)是千萬級的,而且是生產(chǎn)系統(tǒng)。也就是說,不能把所有的記錄都刪除,而且必須快速的把重復記錄刪掉。
對此,總結(jié)了一下刪除重復記錄的方法,以及每種方法的優(yōu)缺點。
為了陳訴方便,假設表名為Tbl,表中有三列col1,col2,col3,其中col1,col2是主鍵,并且,col1,col2上加了索引。
1、通過創(chuàng)建臨時表
可以把數(shù)據(jù)先導入到一個臨時表中,然后刪除原表的數(shù)據(jù),再把數(shù)據(jù)導回原表,SQL語句如下:
creat table tbl_tmp (select distinct* from tbl);truncate table tbl;//清空表記錄insert into tbl select * from tbl_tmp;//將臨時表中的數(shù)據(jù)插回來。
這種方法可以實現(xiàn)需求,但是很明顯,對于一個千萬級記錄的表,這種方法很慢,在生產(chǎn)系統(tǒng)中,這會給系統(tǒng)帶來很大的開銷,不可行。
2、利用rowid
在oracle中,每一條記錄都有一個rowid,rowid在整個數(shù)據(jù)庫中是唯一的,rowid確定了每條記錄是oracle中的哪一個數(shù)據(jù)文件、塊、行上。在重復的記錄中,可能所有列的內(nèi)容都相同,但rowid不會相同。SQL語句如下:
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)知道每條記錄只有一條重復的,這個sql語句適用。但是如果每條記錄的重復記錄有N條,這個N是未知的,就要考慮適用下面這種方法了。
3、利用max或min函數(shù)
這里也要使用rowid,與上面不同的是結(jié)合max或min函數(shù)來實現(xiàn)。SQL語句如下
delete from tbl awhere rowid not in (select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2);//這里max使用min也可以
或者用下面的語句
delete from tbl awhere rowid<(select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2);//這里如果把max換成min的話,前面的where子句中需要把"<"改為">"
跟上面的方法思路基本是一樣的,不過使用了group by,減少了顯性的比較條件,提高效率。SQL語句如下:
deletefrom tbl where rowid not in (select max(rowid) from tbl tgroup by t.col1, t.col2);delete from tbl where (col1, col2) in (select col1,col2 from tblgroup bycol1,col2havingcount(*) >1)and rowidnotin(selectnin(rowid)fromtblgroup bycol1,col2havingcount(*) >1)
還有一種方法,對于表中有重復記錄的記錄比較少的,并且有索引的情況,比較適用。假定col1,col2上有索引,并且tbl表中有重復記錄的記錄比較少,SQL語句如下4、利用group by,提高效率
對此,總結(jié)了一下刪除重復記錄的方法,以及每種方法的優(yōu)缺點。
為了陳訴方便,假設表名為Tbl,表中有三列col1,col2,col3,其中col1,col2是主鍵,并且,col1,col2上加了索引。
1、通過創(chuàng)建臨時表
可以把數(shù)據(jù)先導入到一個臨時表中,然后刪除原表的數(shù)據(jù),再把數(shù)據(jù)導回原表,SQL語句如下:
creat table tbl_tmp (select distinct* from tbl);truncate table tbl;//清空表記錄insert into tbl select * from tbl_tmp;//將臨時表中的數(shù)據(jù)插回來。
這種方法可以實現(xiàn)需求,但是很明顯,對于一個千萬級記錄的表,這種方法很慢,在生產(chǎn)系統(tǒng)中,這會給系統(tǒng)帶來很大的開銷,不可行。
2、利用rowid
在oracle中,每一條記錄都有一個rowid,rowid在整個數(shù)據(jù)庫中是唯一的,rowid確定了每條記錄是oracle中的哪一個數(shù)據(jù)文件、塊、行上。在重復的記錄中,可能所有列的內(nèi)容都相同,但rowid不會相同。SQL語句如下:
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)知道每條記錄只有一條重復的,這個sql語句適用。但是如果每條記錄的重復記錄有N條,這個N是未知的,就要考慮適用下面這種方法了。
3、利用max或min函數(shù)
這里也要使用rowid,與上面不同的是結(jié)合max或min函數(shù)來實現(xiàn)。SQL語句如下
delete from tbl awhere rowid not in (select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2);//這里max使用min也可以
或者用下面的語句
delete from tbl awhere rowid<(select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2);//這里如果把max換成min的話,前面的where子句中需要把"<"改為">"
跟上面的方法思路基本是一樣的,不過使用了group by,減少了顯性的比較條件,提高效率。SQL語句如下:
deletefrom tbl where rowid not in (select max(rowid) from tbl tgroup by t.col1, t.col2);delete from tbl where (col1, col2) in (select col1,col2 from tblgroup bycol1,col2havingcount(*) >1)and rowidnotin(selectnin(rowid)fromtblgroup bycol1,col2havingcount(*) >1)
還有一種方法,對于表中有重復記錄的記錄比較少的,并且有索引的情況,比較適用。假定col1,col2上有索引,并且tbl表中有重復記錄的記錄比較少,SQL語句如下4、利用group by,提高效率
相關(guān)文章
Oracle數(shù)據(jù)庫時間格式轉(zhuǎn)換的常見示例
這篇文章主要給大家介紹了關(guān)于Oracle數(shù)據(jù)庫時間格式轉(zhuǎn)換的常見示例,在實際的工作中會經(jīng)常會用到to_char()、to_date()函數(shù)來對時間、日期進行處理,文中給出了詳細的代碼示例,需要的朋友可以參考下2024-02-02
Oracle數(shù)據(jù)庫常用命令整理(實用方法)
這篇文章主要介紹了Oracle數(shù)據(jù)庫常用命令整理(實用方法),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
Oracle中Union與Union All的區(qū)別(適用多個數(shù)據(jù)庫)
如果我們需要將兩個select語句的結(jié)果作為一個整體顯示出來,我們就需要用到union或者union all關(guān)鍵字。union(或稱為聯(lián)合)的作用是將多個結(jié)果合并在一起顯示出來2012-07-07
Oracle數(shù)據(jù)庫中保留小數(shù)點后兩位的問題解讀
在Oracle數(shù)據(jù)庫中,對數(shù)字和百分比進行格式化,以保留兩位小數(shù),主要使用to_char()函數(shù),對于大數(shù)字如10000000.12,使用to_char(字段名, 'FM99999999999990.00')可確保保留兩位小數(shù)而無額外空格,對于百分比如86.63%2024-09-09
在oracle 數(shù)據(jù)庫查詢的select 查詢字段中關(guān)聯(lián)其他表的方法
在實際開發(fā)過程中,特別是在做數(shù)據(jù)查詢的時候,能夠根據(jù)動態(tài)生成的sql語句將查詢的結(jié)果轉(zhuǎn)化并返回到業(yè)務處理邏輯(或頁面展示出來)能大大的減輕業(yè)務邏輯的處理復雜度。2009-08-08
Plsql Developer連接Oracle時出現(xiàn)Could not initialize oci.dll解決方案
這篇文章主要介紹了Plsql Developer連接Oracle時出現(xiàn)Could not initialize oci.dll解決方案,需要的朋友可以參考下2017-03-03

