当前位置:网站首页>使用SQL进行数据去重的N种方法
使用SQL进行数据去重的N种方法
2022-06-27 20:15:00 【墨天轮】
记得很多年前,有个测试妹子找到我:
强哥,我这个表数据重复了,怎么把重复的数据删掉呀?
类似的需要将数据去重的场景,在实际工作中还是比较常见的。
今天我们就来说说,使用SQL语句来去重,有哪些常见的方法。
假如我们有一张student表:
create table student(id int,name varchar(50),age int,address varchar(100));
表中的数据如下:

方法一:使用DISTINCT关键字进行去重。
DISTINCT关键字,在使用时,后面会跟上去重的字段。可以保证这些去重字段的数据不重复。
比如,取出student表中,不重复的address有哪些,可以使用如下SQL语句:
select distinct addressfrom student;
返回结果如下:

这种方法,最大的优点是使用起来比较简单。
但也有一个比较大的缺点,就是去重的字段与最终返回的结果集中的字段,是一致的。也就是说,在上面的SQL语句中,使用address字段进行去重,最终的结果,也只返回address一个字段。
如果想以address字段去重,并且同时返回其他字段,DISTINCT是做不到的。
方法二:使用GROUP BY关键字进行去重
与DISTINCT关键字一样,GROUP BY关键字,也是标准SQL支持的常用的去重方法。它可以在去重的同时,同步返回其他字段的信息。
还是以对address字段进行去重为例,其他字段可以使用聚合函数根据需要进行获取:
select min(id),max(name),max(age),addressfrom studentgroup by address;
返回结果如下:

在上面的语句中,不仅对address字段进行了去重,也同时返回了id、name、age字段的信息。
在这一点上,比DISTINCT要好用很多。
不过,仔细一看,好像总是觉得哪里不对劲。
id=1的学生,应该叫周俊廷,而在上面的返回结果中却是杨萧语,返回的age字段,也有同样的问题。
也就是说,在返回的结果中,同一行的id、name、age,可能并不是同一个学生的,这就导致看起来数据有些混乱。
如果对数据的一致性有要求,可以使用下面的第三种方法。
方法三:使用窗口函数进行去重。
窗口函数有好几种,使用起来大同小异,这里只介绍ROW_NUMBER() over(partition by ... order by ...)。
selectid,name,age,addressfrom (select id,name,age,address,row_number() over(partition by addressorder by id asc) as rnfrom student)awhere a.rn = 1;
ROW_NUMBER()窗口函数的含义是,先对数据按照partition by的字段进行分组,然后以order by的字段进行排序,序号从1开始递增。
上面的SQL返回的结果为:

这个返回结果,就完美多了。
但是,需要注意的是,有些数据库是不支持窗口函数的。像MySQL数据库中就无法使用。
方法四:使用IN去重
这种方法的关键在于,找到一组不重复的数据的特征,然后以这个特征来取数据。
比如:按address来去重,如果数据有重复,取id最大的那条。
select *from studentwhere id in (select max(id)from studentgroup by address);
SQL返回结果如下:

当然,也可以取id最小的那条,将上面语句中的max改成min就可以了。
这种方法适合表里有一个数据不重复的字段(上面SQL中的id字段)的情况。
如果表中不存在这样一个字段,这种方法就不再适用了。但有些数据库,天生自带了类似的字段可以使用。
比如,在ORACLE数据库中,可以使用ROWID替代上面SQL中的id字段。当然仅限于ORACLE数据库:
select *from studentwhere rowid in (select max(rowid)from studentgroup by address);
方法五:使用NOT EXISTS去重
与方法四的思路类似,使用NOT EXISTS也可以实现同样的效果。
select *from student awhere not exists(select 1from student bwhere a.address = b.addressand a.id > b.id);
SQL返回结果如下:

方法六:使用ALL关键字
在MySQL数据库中,有一个特殊的操作符ALL,这是一个集合操作符。
select *from student awhere a.id <= ALL(select b.idfrom student bwhere a.address = b.address);
SQL返回结果如下:

在上面的SQL中,ALL操作符的意思是说,a.id字段要<=ALL操作符括号里查询出来的所有值。
所以,这种方法的核心思路与方法四是类似的。
方法七:使用INNER JOIN + GROUP BY关键字
这种方法的核心思路,也与方法四是类似的。
selecta.*from student ainner join student bon a.address = b.addressand a.id >= b.idgroup by a.id,a.name,a.age,a.addresshaving count(*)=1;
SQL返回结果如下:

熟练使用上面7种数据去重的方法,基本上可以解决所有的数据去重问题了。
当然,如果你还有更好的方法,欢迎在下面留言。
ps. 点击下方阅读原文,可下载文章中使用的素材及SQL语句范例。也可加我微信201855204获取。
推荐阅读:
边栏推荐
- Using the cucumber automated test framework
- About the SQL injection of davwa, errors are reported: analysis and verification of the causes of legal mix of settlements for operation 'Union'
- 微服务之服务网关
- Stunned! The original drawing function of markdown is so powerful!
- Hiplot 在线绘图工具的本地运行/开发库开源
- Vue+mysql login registration case
- 跟着存档教程动手学RNAseq分析(三):使用DESeq2进行计数标准化
- ABAP essay - material master data interface enhancement - tab enhancement
- Is it safe to open a stock account through the account opening link given by the CICC securities manager? I want to open an account
- 【经典干货书】数据科学中的信息理论方法,561页pdf
猜你喜欢

Introduction to MySQL operation (IV) -- data sorting (ascending, descending, and multi field sorting)

Penetration learning - shooting range chapter - detailed introduction to Pikachu shooting range (under continuous update - currently only the SQL injection part is updated)

Transformation from student to engineer

How to use RPA to achieve automatic customer acquisition?

99 multiplication table - C language

netERR_ CONNECTION_ Refused solution

C # QR code generation and recognition, removing white edges and any color

最虚的华人首富更虚了

The "business and Application Security Development Forum" held by the ICT Institute was re recognized for the security capability of Tianyi cloud

广告太「野」,吉野家「渡劫」
随机推荐
【微服务】(十六)—— 分布式事务Seata
average-population-of-each-continent
Do280openshift access control -- Security Policy and chapter experiment
「R」使用ggpolar绘制生存关联网络图
使用同花顺手机炒股安全吗?
《7天学会Go并发编程》第六天 go语言Sync.cond的应用和实现 go实现多线程联合执行
Flask application case
爬虫笔记(2)- 解析
How to prioritize the contents in the queue every second
【经典干货书】数据科学中的信息理论方法,561页pdf
「R」 Using ggpolar to draw survival association network diagram
Re recognize G1 garbage collector through G1 GC log
99 multiplication table - C language
How to open an account for agricultural futures? How much is the handling charge for opening an account for futures? Who can give you a preferential handling charge?
Consumer finance app user insight in the first quarter of 2022 - a total of 44.79 million people
移动端避免使用100vh[通俗易懂]
同花顺炒股软件可靠吗??安全嘛?
Solve the problem that the virtual machine cannot be connected locally
跟着存档教程动手学RNAseq分析(二)
Using the cucumber automated test framework