SQL小技巧5:数据去重的N种方法,总有一种你想不到!

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

在平时工作中,使用SQL语句进行数据去重的场景非常多。

今天主要分享几种数据去重的SQL写法。

假如有一张student表,结构如下:

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

表中的数据如下:

图片

方法一:使用DISTINCT关键字进行去重

在使用DISTINCT关键字去重时,后面跟上去重的字段即可。

比如,取出student表中,不重复的address有哪些,可以使用如下SQL语句:

select distinct address from student;

返回结果如下:

图片

这种方法,最大的优点是使用起来比较简单。

但也有一个比较大的缺点,就是最终返回的结果集中的字段最多只包含去重的字段。也就是说,在上面的SQL语句中,使用address字段进行去重,最终的结果,也最多只能返回address一个字段。

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

方法二:使用GROUP BY关键字进行去重

与DISTINCT关键字一样,GROUP BY关键字,也是标准SQL支持的常用的去重方法。它可以在去重的同时,同步返回其他字段的信息。

还是以对address字段进行去重为例,其他字段可以使用聚合函数根据需要进行获取:

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

返回结果如下:

图片

在上面的语句中,不仅对address字段进行了去重,也同时返回了id、name、age字段的信息。

在这一点上,比DISTINCT要好用很多。

不过,仔细一看,好像总是觉得哪里不对劲。

id=1的学生,应该叫周俊廷,而在上面的返回结果中却是杨萧语,返回的age字段,也有同样的问题。

也就是说,在返回的结果中,同一行的id、name、age,可能并不是同一个学生的,这就导致看起来数据有些混乱。

如果对数据的一致性有要求,可以使用下面的第三种方法。

方法三:使用窗口函数进行去重

窗口函数有好几种,使用起来大同小异,这里只介绍ROW_NUMBER() over(partition by ... order by ...)。

select    id,name,age,addressfrom (    select id,name,age,address,        row_number() over(            partition by address             order by id asc        ) as rn    from 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 student     group by address);

返回结果如下:

图片

当然,也可以取id最小的那条,将上面语句中的max改成min就可以了。

这种方法适合表里有一个数据不重复的字段(如上面SQL中的id字段)的情况。

如果表中不存在这样一个字段,这种方法就不再适用了。但有些数据库,天生自带了类似的字段可以使用。

比如,在ORACLE数据库中,可以使用ROWID替代上面SQL中的id字段。当然仅限于ORACLE数据库:

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

方法五:使用NOT EXISTS去重

与方法四的思路类似,使用NOT EXISTS也可以实现同样的效果。

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

返回结果如下:

图片

方法六:使用ALL关键字

在MySQL数据库中,有一个特殊的操作符ALL,这是一个集合操作符,表示子数据集中的所有数据都满足某一个条件。

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

返回结果如下:

图片

在上面的SQL中,ALL操作符的意思是说,a.id字段要<=ALL操作符括号里查询出来的所有值。

这种方法的核心思路与方法四是类似的。

方法七:使用INNER JOIN + GROUP BY关键字

这种方法的核心思路,也与方法四是类似的。

select    a.*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;

返回结果如下:

图片

上面介绍了7种数据去重的方法,你知道几种?

【关注微信公众号:跟强哥学SQL,回复“笔试”免费领取大厂SQL笔试题。】

SQL SELECT DISTINCT 语句详解:精准的艺术 DISTINCT是 SQL 中的一个关键字,用于从查询结果中复的记录。当你只关心查询结果中每个唯一值时,DISTINCT能有效地帮助你精简结果集。:指定你想要查询的列。table_name:查询的目标表。是一个强大的工具,能够帮助我们精准地从查询结果中数据。在日常开发中,理解其工作原理和常见的应用场景,可以有效提升数据查询的效率和准确性。单列或多列DISTINCT可以应用于单列或多列,用于数据。与聚合函数结合DISTINCT可以和聚合函数一起使用,进行更复杂的数据分析 阅读详情

相关推荐

解决大规模数据抓取问题:Python 爬虫如何实现数据与增量更新

摘要: 本文探讨了Python爬虫在大规模数据抓取中的两个关键技术——数据与增量更新。针对复抓取导致的资源浪费和数据污染问题,提出了URL哈希(Redis存储)、内容比对及数据库方法。对于增量更新,介绍了基于时间戳、API接口及数据库比对等策略,并给出SQLite和Redis的代码示例(如定时任务schedule)。通过优化存储、并发抓取(多线程)和批量处理,可显著提升爬虫效率与数据准确性。适用于高频更新或海量数据的采集场景。 核心标签: #Python爬虫 #数据 #增量更新 #Red

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 953

SQL数据的三种方法

SQL数据

qq_35091353的博客 15万+

FlinkSql系列8之TopN&

FlinkSql系列8之TopN& 文章目录FlinkSql系列8之TopN&前言一、TopN二、WindowTopN三、Deduplication结 前言 本次主要记录FLinkSql中的TopN以及。 一、TopN 建立数据源表 CREATE TABLE source_table5( --姓名 `name` STRING, --班级 `class_id` BIGINT, --分数 `score` BIGINT, --事件时间 `row_time` TIMESTAMP(3)

feiyangailing的博客 2574

数据库语句整理

数据库语句整理

qq_35466392的博客 6650

6种SQL数据技巧!

6种SQL数据技巧!

eagle89的专栏 3万+

5个必须掌握的SQL数据技巧:从DISTINCT到NULL值处理全攻略

数据处理中,准确和NULL值管理是确保分析结果可靠性的基础。本文将通过5个实用技巧,帮助你轻松掌握SQL中DISTINCT关键字的使用方法和NULL值的处理策略,提升数据清洗效率。 ### 技巧1:基础——使用DISTINCT获取唯一值 当需要从表中提取不复的记录时,`DISTINCT`关键字是最直接的解决方案。它会过滤掉指定列中的复值,只返回唯一结果。 **基本语法**: ``

gitblog_00362的博客 547

27、Flink 的SQL之SELECT (Top-N、Window Top-N 窗口 Top-N 和 Window Deduplication 窗口)介绍及详细示例(6)

对于流式处理查询,与连续表上的常规 Top-N 不同,窗口 Top-N 不会发出中间结果,而只会发出最终结果,即窗口末尾的前 N 条记录数。此外,Window Top-N可以与基于窗口TVF的其他操作一起使用,例如窗口聚合,窗口TopN和窗口联接。因此,如果用户不需要更新每条记录的结果,则窗口数据删除查询具有更好的性能。以下面的作业为例,假设product_id是 ShopSales 的唯一键,那么 Top-N 查询的唯一键是 [category, rownum] 和 [product_id]。

alanchanchn的专栏 7万+

SQL :如何保留“最新”的一条数据?只用 DISTINCT 可做不到!

简单,用DISTINCT。聚合统计,用GROUP BY。复杂逻辑(保留特定行),用。别再因为“听说DISTINCT慢”就盲目使用GROUP BY了。在现代数据库优化器面前,它俩在纯场景下是半斤八两的。真正拉开差距的,是你的业务需求到底需要多精细的控制粒度。

郑龙飞 1193

SQL 查询优化的常用模式:避免 N+1、合理分页与

N+1 查询是 ORM 使用中最常见、影响最大的性能问题。场景:你需要查询 10 个用户及其各自的订单数量。共执行了 11 次查询 (1 + 10)。如果有 100 个用户,就是 101 次查询。如果每次查询耗时 5ms,通常不会注意到;但如果数据库部署在云端,每次查询的网络往返 (RTT) 可能是 50ms,101 次查询就是 5 秒——用户体验从「瞬间加载」变成了「明显卡顿」。这种性能瓶颈的核心在于查询结构的耗时分布。

weixin_63764436的博客 3869

Flink SQL Deduplication用 ROW_NUMBER 做流式

Flink SQL(Deduplication)是流式数据处理中移除复记录的关键操作,通过保留每组键(PARTITION BY)的第一条或最后一条记录(由时间属性ORDER BY决定)。标准写法包括QUALIFY或子查询+ROW_NUMBER=1两种模式,需确保排序使用处理时间或事件时间。事件时间排序结果更稳定,而处理时间可能波动。会产生更新流,要求下游支持upsert机制。需注意状态管理,合理设置TTL避免状态膨胀。常见错误包括缺少rownum=1条件、使用非时间属性排序、下游不支持更新流等

hello.reader 1299

sql分组_在文件上使用 SQL 查询的示例

数据分析业务中经常要处理数据文件。我们知道,对于数据库中的数据,使用SQL来查询是非常方便快捷的,所以很容易想到把文件数据先导入到数据库再用SQL来查询。但是文件数据导入数据库本身也是很繁琐的工作,那么有没有直接对数据文件使用SQL查询的办法呢?本文将介绍这样的办法,列举出用 SQL 查询文件数据的各种情况,并提供用 esProc SPL 编写的代码示例。esProc 是专业的数据计算引擎,SP...

weixin_39724287的博客 541

Flink SQL的Top-N实战

1 Top-N       目前仅Blink计划器支持Top-N。       Top-N查询时根据列排序找到N个最大或最小的值。最大值集合最小值集都被视为是一种Top-N的查询。若在批处理或流处理的表中需要显示出满足条件的N个最底层记录或最顶层记录,Top-N查询将会十分有用。得到的结果集将可以进行进一步的分析。       F

huahuaxiaoshao的博客 2414

SQL:实现漏斗、留存、Top-N、、行转列/列转行

本文介绍了MySQL 8中用户行为数据分析的常用SQL查询模式。主要包括:1)建立events表及优化索引建议(如(user_id,event_time)组合索引);2)漏斗分析三种实现方式(用户级、按日期分组、会话内);3)留存分析(通过cohort_dt和active_dt计算);4)分组Top-N查询方法5数据技巧;6)行列转换技术。文章还展示了如何利用EXPLAIN和EXPLAIN ANALYZE进行查询优化分析,为常见的用户行为分析场景提供了实用的SQL解决方案。

lishifu_的博客 567

UNION与UNION ALL:从执行计划看懂SQL与性能优化

SQL查询优化中,集合操作是处理多表数据合并的常用手段,而UNION和UNION ALL的选择直接影响数据库性能。二者表面区别是“”与“不”,但底层却涉及排序、哈希算法、临时表乃至内存溢出等关键机制。理解执行计划中的UNION RESULT、SORT UNIQUE或HashAggregate,有助于开发者在真实业务中避免慢SQL和磁盘爆满问题。针对流水表合并、结果集聚合、唯一集合归并等场景,合理选用操作符能显著提升查询效率。同时,不同数据库对UNION的类型兼容、ORDER BY和LIMIT处理存

weixin_30566111的博客 357

别再写错Flink SQL了!用Window Top-N和Deduplication搞定实时排行榜与数据(Flink 1.17实战)

本文详细介绍了Flink SQL中Window Top-N和Deduplication的高效应用,帮助开发者解决实时排行榜与数据问题。通过对比常规Top-N与Window Top-N的差异,以及DISTINCT与Window Deduplication的优劣,提供性能优化和异常处理方案,适用于电商、金融等实时数据处理场景。

weixin_38169206的博客 392

Flink SQL 中的 SELECT DISTINCT批流一体下的与状态管理

Flink SQL 中 SELECT DISTINCT 在批处理和流处理中的表现差异显著。批处理时与传统数据库行为一致,一次性扫描并。但在流处理中,需要持续维护"已出现集合"状态,可能导致状态无限增长。可通过配置状态TTL控制内存占用,但会牺牲正确性。实际应用中需区分需求:全局唯一适合批处理;时间范围建议使用窗口函数;按主键保留最新记录更适合ROW_NUMBER方案。流处理中使用DISTINCT前需评估业务对"过期后算"的容忍度及key基数大小,谨慎

hello.reader 943

哈希深度解析

在分布式系统中,传统哈希取模算法(hash(key) % N)存在致命缺陷:节点增减导致大量数据定位,引发缓存雪崩。示例:在Memcached集群中,若新增节点Server4,仅需迁移Server3到Server4之间的数据,而非全量迁移。原理:通过位数组和多个哈希函数表示集合,查询时若所有哈希位均为1则可能存在(允许误判),否则一定不存在。哈希环:将哈希空间映射为环形结构(0~2^32-1),节点与数据均通过哈希函数映射到环上。优势:空间效率极高(1亿数据仅需12MB内存),适合海量数据

小新阿呆的博客 1613

flinksql flinktable TopN 或者

目的 实现flink sql 或者求TopN.其实就是求Top1 TopN官方文档(在同一页面) 代码 package UserBehiverAnalysis import org.apache.flink.streaming.api.TimeCharacteristic import org.apache.flink.table.api._ import org.apache.flink.table.api.bridge.scala._ import org.apache.f...

yy的博客 964
上一篇: 单挑力扣(LeetCode)SQL题:534. 游戏玩法分析 III(难度:中等)
下一篇: 单挑力扣(LeetCode)SQL题:1951. 查询具有最多共同关注者的所有两两结对组(难度:中等)
小_强
博客等级 码龄19年 1402粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值