亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SQL數(shù)據(jù)去重的七種方法小結(jié)

 更新時(shí)間:2024年03月15日 10:56:06   作者:小_強(qiáng)  
在平時(shí)工作中,使用SQL語(yǔ)句進(jìn)行數(shù)據(jù)去重的場(chǎng)景非常多,本文主要介紹了SQL數(shù)據(jù)去重的七種方法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在平時(shí)工作中,使用SQL語(yǔ)句進(jìn)行數(shù)據(jù)去重的場(chǎng)景非常多。

今天主要分享幾種數(shù)據(jù)去重的SQL寫(xiě)法。

假如有一張student表,結(jié)構(gòu)如下:

create table student(
    id int,
    name varchar(50),
    age int,
    address varchar(100)
);

表中的數(shù)據(jù)如下:

圖片

方法一:使用DISTINCT關(guān)鍵字進(jìn)行去重

在使用DISTINCT關(guān)鍵字去重時(shí),后面跟上去重的字段即可。

比如,取出student表中,不重復(fù)的address有哪些,可以使用如下SQL語(yǔ)句:

select distinct address 
from student;

返回結(jié)果如下:

圖片

這種方法,最大的優(yōu)點(diǎn)是使用起來(lái)比較簡(jiǎn)單。

但也有一個(gè)比較大的缺點(diǎn),就是最終返回的結(jié)果集中的字段最多只包含去重的字段。也就是說(shuō),在上面的SQL語(yǔ)句中,使用address字段進(jìn)行去重,最終的結(jié)果,也最多只能返回address一個(gè)字段。

如果想以address字段去重,并且同時(shí)返回其他字段,DISTINCT是做不到的。

方法二:使用GROUP BY關(guān)鍵字進(jìn)行去重

與DISTINCT關(guān)鍵字一樣,GROUP BY關(guān)鍵字,也是標(biāo)準(zhǔn)SQL支持的常用的去重方法。它可以在去重的同時(shí),同步返回其他字段的信息。

還是以對(duì)address字段進(jìn)行去重為例,其他字段可以使用聚合函數(shù)根據(jù)需要進(jìn)行獲?。?/p>

select min(id),
    max(name),
    max(age),
    address
from student 
group by address;

返回結(jié)果如下:

圖片

在上面的語(yǔ)句中,不僅對(duì)address字段進(jìn)行了去重,也同時(shí)返回了id、name、age字段的信息。

在這一點(diǎn)上,比DISTINCT要好用很多。

不過(guò),仔細(xì)一看,好像總是覺(jué)得哪里不對(duì)勁。

id=1的學(xué)生,應(yīng)該叫周俊廷,而在上面的返回結(jié)果中卻是楊蕭語(yǔ),返回的age字段,也有同樣的問(wèn)題。

也就是說(shuō),在返回的結(jié)果中,同一行的id、name、age,可能并不是同一個(gè)學(xué)生的,這就導(dǎo)致看起來(lái)數(shù)據(jù)有些混亂。

如果對(duì)數(shù)據(jù)的一致性有要求,可以使用下面的第三種方法。

方法三:使用窗口函數(shù)進(jìn)行去重

窗口函數(shù)有好幾種,使用起來(lái)大同小異,這里只介紹ROW_NUMBER() over(partition by ... order by ...)。

select
    id,name,age,address
from (
    select id,name,age,address,
        row_number() over(
            partition by address 
            order by id asc
        ) as rn
    from student
)a
where a.rn = 1;

ROW_NUMBER()窗口函數(shù)的原理是,先對(duì)數(shù)據(jù)按照partition by的字段進(jìn)行分組,然后以order by的字段在各個(gè)分組內(nèi)進(jìn)行排序,序號(hào)從1開(kāi)始遞增。

上面的SQL返回的結(jié)果為:

圖片

這個(gè)返回結(jié)果,就完美多了。

但是,需要注意的是,有些數(shù)據(jù)庫(kù)是不支持窗口函數(shù)的。像低版本的MySQL數(shù)據(jù)庫(kù)中就無(wú)法使用。

方法四:使用IN去重

這種方法的關(guān)鍵在于,找到一組不重復(fù)的數(shù)據(jù)的特征,然后以這個(gè)特征來(lái)取數(shù)據(jù)。

比如:按address來(lái)去重,如果數(shù)據(jù)有重復(fù),取id最大的那條。

select * 
from student
where id in (
    select max(id) 
    from student 
    group by address
);

返回結(jié)果如下:

圖片

當(dāng)然,也可以取id最小的那條,將上面語(yǔ)句中的max改成min就可以了。

這種方法適合表里有一個(gè)數(shù)據(jù)不重復(fù)的字段(如上面SQL中的id字段)的情況。

如果表中不存在這樣一個(gè)字段,這種方法就不再適用了。但有些數(shù)據(jù)庫(kù),天生自帶了類似的字段可以使用。

比如,在ORACLE數(shù)據(jù)庫(kù)中,可以使用ROWID替代上面SQL中的id字段。當(dāng)然僅限于ORACLE數(shù)據(jù)庫(kù):

select * 
from student
where rowid in (
    select max(rowid) 
    from student 
    group by address
);

方法五:使用NOT EXISTS去重

與方法四的思路類似,使用NOT EXISTS也可以實(shí)現(xiàn)同樣的效果。

select *
from student a
where not exists(
    select 1 
    from student b 
    where a.address = b.address 
      and a.id > b.id
);

返回結(jié)果如下:

圖片

方法六:使用ALL關(guān)鍵字

在MySQL數(shù)據(jù)庫(kù)中,有一個(gè)特殊的操作符ALL,這是一個(gè)集合操作符,表示子數(shù)據(jù)集中的所有數(shù)據(jù)都滿足某一個(gè)條件。

select *
from student a
where a.id <= ALL(
    select b.id
    from student b
    where a.address = b.address
);

返回結(jié)果如下:

圖片

在上面的SQL中,ALL操作符的意思是說(shuō),a.id字段要<=ALL操作符括號(hào)里查詢出來(lái)的所有值。

這種方法的核心思路與方法四是類似的。

方法七:使用INNER JOIN + GROUP BY關(guān)鍵字

這種方法的核心思路,也與方法四是類似的。

select
    a.*
from student a
inner join student b
on a.address = b.address
and a.id >= b.id
group by a.id,a.name,a.age,a.address
having count(*)=1;

返回結(jié)果如下:

圖片

上面介紹了7種數(shù)據(jù)去重的方法,你知道幾種?

到此這篇關(guān)于SQL數(shù)據(jù)去重的七種方法小結(jié)的文章就介紹到這了,更多相關(guān)SQL數(shù)據(jù)去重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論