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