1. 程式人生 > 其它 >sql left join 去重_混入了一些奇怪的東西?SQL小技巧之資料去重

sql left join 去重_混入了一些奇怪的東西?SQL小技巧之資料去重

技術標籤:sql left join 去重sql sum 去重sql 去重並統計總數sql 去重查詢sql 去重求和sql 結果去重

大家好,歡迎踏入野生程式猿的生存之道,我是你們的老朋友大猿猿!

今天聊聊資料庫裡怎樣刪除重複資料。

“重複”的定義

首先咱先明確一下什麼叫重複資料,比如你有個表,好比說學生表吧,這個表裡出現了兩條一模一樣的資料,姓名、性別、出生日期、學號、等等等等,全都一樣,那麼這兩條資料就叫重複資料。當然,重複的也不一定是兩條,可能一個學生出現了20條,這20條都是重複的,或者張三出現了3條,李四出現了4條等等。

110333338af6a1ecfb01f580ae860348.png

有主鍵

3f99b0ac92d01c9a4abb7eb66347ee0d.png

無主鍵

重複資料又可分為兩種情況,第一種是這個表連主鍵都沒有,所有欄位全重複。第二種是這個表有主鍵,除了主鍵外的其他欄位重複。

我們的目標

說到這裡大家應該瞭解了,本文裡的重複資料其實算是一種垃圾資料,它本不該出現,但由於各種原因,比如你導資料時重複操作了,比如你儲存按鈕沒做控制而又發生了連擊現象,等等等等。

那麼出現了重複資料,我們期望怎麼辦呢?當然是把多餘的刪掉,只保留一條

解決辦法--有主鍵

我們先捋捋思路,假設某個重複資料有n條,那麼我們要刪掉n-1條,留下1條,而留下的這個“1”,其實和其他資料沒有任何區別,那麼我們怎麼定位出這個“1”呢?怎麼讓這個“1”和其他資料有所不同呢?說到這裡,應該有同學想到了,主鍵肯定不一樣!沒錯,我們就可以用主鍵區分,一不做二不休,我們就留主鍵最大的那個!直接上SQL:

delete from student T1 where id <> (select max(id) from student T2 where T1.name = T2.name and T1.age = T2.age and T1.gender = T2.gender and T1.national = T2.national and T1.addr = T2.addr)

為了保險起見,我們先把delete改成select *,看看要刪的內容是不是和我們預想的一樣:

d482ebd4cc819a19a97d665324148125.png

可以看到,確實查出來的是重複的,且ID不是相同資料中最大的。我們執行delete,然後再看錶中資料:

61eb3d0746969ce318b59777b9282755.png

可以看到,重複資料已經被刪除了。注意,例子中,張三隻有3條重複,另外一個張三隻是恰好重名而已,其他資訊不同。

解決辦法--無主鍵

方案一:

對於無主鍵的情況思路也是完全一樣,但是這裡出現問題了,沒有ID怎麼辦?大家不妨這樣想,雖然兩行資料一模一樣,但是資料庫自己卻能區分出誰是誰,那麼資料庫中肯定還有其他標識以供區分!比如oracle,就會有個隱藏欄位rowid。(如果你用的那個資料庫他偏偏就是沒有這麼個標識,那就只能先給這個表加一列,然後給這列賦值成一個自增序列)

我們先把這個欄位查出來看看它的真容:

select T.rowid,T.* from student T
8cb52d9a513ab0bb74b2db2ee657436d.png

雖然我們不知道rowid裡到底存的是啥意思,但可以肯定的一點是,它不會和別的行重複,於是我們剛才的那個sql只需改成這樣就行了:

delete from student T1 where rowid <> (select max(rowid) from student T2 where T1.name = T2.name and T1.age = T2.age and T1.gender = T2.gender and T1.national = T2.national and T1.addr = T2.addr)

方案二:

還有另一種方案,稍微笨一點。大家查詢時去除重複都知道怎麼寫吧?沒錯:

select distinct * from student

看結果:

7ba8d3f56a1f208152350e049c2e03df.png

那麼我們只需基於這個查詢新建個表,然後再把原來的表幹掉,最後再給新建的表改改名就OK啦:

create table student_temp as select distinct * from dy.student;drop table student;alter table student_temp rename to student;

為什麼說這個方案稍微笨一點呢?因為你建完表後,還要注意原表有沒有索引、許可權、觸發器等一系列相關的東西,如果有,你還得重新把這些東西建上。

好了小夥伴們,你學會了嗎?點我頭像能學習更多實用的開發小技巧,別忘了點關注哦~