sql left join 去重_混入了一些奇怪的东西?SQL小技巧之数据去重
大家好,歡迎踏入野生程序猿的生存之道,我是你們的老朋友大猿猿!
今天聊聊數據庫里怎樣刪除重復數據。
“重復”的定義
首先咱先明確一下什么叫重復數據,比如你有個表,好比說學生表吧,這個表里出現了兩條一模一樣的數據,姓名、性別、出生日期、學號、等等等等,全都一樣,那么這兩條數據就叫重復數據。當然,重復的也不一定是兩條,可能一個學生出現了20條,這20條都是重復的,或者張三出現了3條,李四出現了4條等等。
有主鍵
無主鍵
重復數據又可分為兩種情況,第一種是這個表連主鍵都沒有,所有字段全重復。第二種是這個表有主鍵,除了主鍵外的其他字段重復。
我們的目標
說到這里大家應該了解了,本文里的重復數據其實算是一種垃圾數據,它本不該出現,但由于各種原因,比如你導數據時重復操作了,比如你保存按鈕沒做控制而又發生了連擊現象,等等等等。
那么出現了重復數據,我們期望怎么辦呢?當然是把多余的刪掉,只保留一條。
解決辦法--有主鍵
我們先捋捋思路,假設某個重復數據有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 *,看看要刪的內容是不是和我們預想的一樣:
可以看到,確實查出來的是重復的,且ID不是相同數據中最大的。我們執行delete,然后再看表中數據:
可以看到,重復數據已經被刪除了。注意,例子中,張三只有3條重復,另外一個張三只是恰好重名而已,其他信息不同。
解決辦法--無主鍵
方案一:
對于無主鍵的情況思路也是完全一樣,但是這里出現問題了,沒有ID怎么辦?大家不妨這樣想,雖然兩行數據一模一樣,但是數據庫自己卻能區分出誰是誰,那么數據庫中肯定還有其他標識以供區分!比如oracle,就會有個隱藏字段rowid。(如果你用的那個數據庫他偏偏就是沒有這么個標識,那就只能先給這個表加一列,然后給這列賦值成一個自增序列)
我們先把這個字段查出來看看它的真容:
select T.rowid,T.* from student T雖然我們不知道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看結果:
那么我們只需基于這個查詢新建個表,然后再把原來的表干掉,最后再給新建的表改改名就OK啦:
create table student_temp as select distinct * from dy.student;drop table student;alter table student_temp rename to student;為什么說這個方案稍微笨一點呢?因為你建完表后,還要注意原表有沒有索引、權限、觸發器等一系列相關的東西,如果有,你還得重新把這些東西建上。
好了小伙伴們,你學會了嗎?點我頭像能學習更多實用的開發小技巧,別忘了點關注哦~
總結
以上是生活随笔為你收集整理的sql left join 去重_混入了一些奇怪的东西?SQL小技巧之数据去重的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea 查看一个类的子类_Java-0
- 下一篇: 为什么 新u盘电脑读不出来怎么回事 新U