SQL中distinct 和 row_number() over() 的区别及用法
发布时间 - 2026-01-10 23:25:17 点击率:次1 前言

在咱们编写 SQL 语句操作数据库中的数据的时候,有可能会遇到一些不太爽的问题,例如对于同一字段拥有相同名称的记录,我们只需要显示一条,但实际上数据库中可能含有多条拥有相同名称的记录,从而在检索的时候,显示多条记录,这就有违咱们的初衷啦!因此,为了避免这种情况的发生,咱们就需要进行“去重”处理啦,那么何为“去重”呢?说白了,就是对同一字段让拥有相同内容的记录只显示一条记录。
那么,如何实现“去重”的功能呢?对此,咱们有两种方式可以实现该功能。
第一种,在编写 select 语句的时候,添加 distinct 关键词;
第二种,在编写 select 语句的时候,调用 row_number() over() 函数。
以上两种方式都可以实现“去重”功能,那两者之间有何异同呢?接下来,作者将给出详细的说明。
2 distinct
在 SQL 中,关键字 distinct 用于返回唯一不同的值。其语法格式为:
SELECT DISTINCT 列名称 FROM 表名称
假设有一个表“CESHIDEMO”,包含两个字段,分别 NAME 和 AGE,具体格式如下:
观察以上的表,咱们会发现:拥有相同 NAME 的记录有两条,拥有相同 AGE 的记录有三条。如果咱们运行下面这条 SQL 语句,
/** * 其中 PPPRDER 为 Schema 的名字,即表 CESHIDEMO 在 PPPRDER 中 */ select name from PPPRDER.CESHIDEMO
将会得到如下结果:
观察该结果,咱们会发现在以上的四条记录中,包含两条 NAME 值相同的记录,即第 2 条记录和第 3 条记录的值都为“gavin”。那么,如果咱们想让拥有相同 NAME 的记录只显示一条该如何实现呢?这时,就需要用到 distinct 关键字啦!接下来,运行如下 SQL 语句,
select distinct name from PPPRDER.CESHIDEMO
将会得到如下结果:
观察该结果,显然咱们的要求得到实现啦!但是,咱们不禁会想到,如果将 distinct 关键字同时作用在两个字段上将会产生什么效果呢?既然想到了,咱们就试试呗,运行如下 SQL 语句,
select distinct name, age from PPPRDER.CESHIDEMO
得到的结果如下所示:
观察该结果,哎呀,貌似没有作用啊?她将全部的记录都显示出来了啊!其中 NAME 值相同的记录有两条,AGE 值相同的记录有三条,完全没有变化啊!但事实上,结果就应该是这样的。因为当 distinct 作用在多个字段的时候,她只会将所有字段值都相同的记录“去重”掉,显然咱们“可怜”的四条记录并不满足该条件,因此 distinct 会认为上面四条记录并不相同。空口无凭,接下来,咱们再向表“CESHIDEMO”中添加一条完全相同的记录,验证一下即可。添加一条记录后的表如下所示:
再运行如下的 SQL 语句,
select distinct name, age from PPPRDER.CESHIDEMO
得到的结果如下所示:
观察该结果,完美的验证了咱们上面的结论。
此外,有一点需要大家特别注意,即:关键字 distinct 只能放在 SQL 语句中所有字段的最前面才能起作用,如果放错位置,SQL 不会报错,但也不会起到任何效果。
3 row_number() over()
在 SQL Server 数据库中,为咱们提供了一个函数 row_number() 用于给数据库表中的记录进行标号,在使用的时候,其后还跟着一个函数 over(),而函数 over() 的作用是将表中的记录进行分组和排序。两者使用的语法为:
ROW_NUMBER() OVER(PARTITION BY COLUMN1 ORDER BY COLUMN2)
意为:将表中的记录按字段 COLUMN1进行分组,按字段 COLUMN2 进行排序,其中
PARTITION BY:表示分组ORDER BY:表示排序
接下来,咱们还用表“CESHIDEMO”中的数据进行测试。首先,给出没有使用 row_number() over() 函数时查询的结果,如下所示:
然后,运行如下 SQL 语句,
select PPPRDER.CESHIDEMO.*, row_number() over(partition by age order by name desc) from PPPRDER.CESHIDEMO
得到的结果如下所示:
从上面的结果可以看出,其在原表的基础上,多了一列标有数字排序的列。那么反过来分析咱们运行的 SQL 语句,发现其确实按字段 AGE 的值进行分组了,也按字段 NAME 的值进行排序啦!因此,函数的功能得到了验证。
接下来,咱们就研究如何用 row_number() over() 函数实现“去重”的功能。通过观察上面的结果,咱们可以发现,如果以 NAME 分组,以 AGE 排序,然后再取每组的第一个记录或许就可以实现“去重”的功能啊!那么试试看,运行如下 SQL 语句,
/* * 其中 rn 表示最后添加的那一列 */ select * from (select PPPRDER.CESHIDEMO.*, row_number() over(partition by name order by age desc) rn from PPPRDER.CESHIDEMO) where rn = 1
运行后,得到的结果如下所示:
观察以上的结果,我们发现,哎呀,数据“去重”的功能一不小心就被咱们实现了啊!不过很遗憾,如果咱们细心的话,会发现一个很不爽的事情,那就是在执行以上 SQL 语句进行“去重”的时候,有一条 NAME 值为“gavin”、AGE 值为“18”的记录被过滤掉了,但是在现实生活会中,同名不同年龄的事情太正常了。
4 总结
通过阅读及实践以上内容,咱们已经知道了,无论是用关键字 distinct 还是用函数 row_number() over() 都可以实现数据“去重”的功能。但是在实现使用的过程中,咱们要特别注意两者的用法特点以及区别。
在使用关键字 distinct 的时候,咱们要知道其作用于单个字段和多个字段的时候是有区别的,作用于单个字段时,其“去重”的是表中所有该字段值重复的数据;作用于多个字段的时候,其“去重”的表中所有字段(即 distinct 具体作用的多个字段)值都相同的数据。
在使用函数 row_number() over() 的时候,其是按先分组排序后,再取出每组的第一条记录来进行“去重”的(在本篇博文中如此)。当然,在此处咱们还可以通过不同的限制条件来进行“去重”,具体如何实现,就需要大家自己去动脑思考啦!
最后,在本篇博文中,作者详述了自己对用关键字 distinct 和函数 row_number() over() 进行数据“去重”的一些认识,希望以上的内容能够对大家有所帮助!
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# SQL中distinct
# 和
# row_number()
# over()区别
# over()对比
# 使用row_number()实现分页实例
# oracle中rownum和row_number()
# 利用ROW_NUMBER() OVER函数给SQL数据库中每一条记录分配行号的方法
# Mysql row number()排序函数的用法和注意
# MYSQL row_number()与over()函数用法详解
# SQL使用ROW_NUMBER() OVER函数生成序列号
# MySQL中rank() over、dense_rank() over、row_
# SQL中row_number() over(partition by)的用法说明
# Row_number()函数用法小结
# 数据库中row_number() 分组排序函数的具体使用
# 关键词
# 所示
# 多个
# 将会
# 两条
# 可以实现
# 数据库中
# 四条
# 作用于
# 只显示
# 用在
# 三条
# 多条
# 值为
# 如何实现
# 每组
# 的是
# 空口无凭
# 博文
# 一个函数
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
深圳网站制作平台,深圳市做网站好的公司有哪些?
如何打造高效商业网站?建站目的决定转化率
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
JS经典正则表达式笔试题汇总
JS去除重复并统计数量的实现方法
怎么用AI帮你设计一套个性化的手机App图标?
Laravel怎么清理缓存_Laravel optimize clear命令详解
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
javascript日期怎么处理_如何格式化输出
北京网站制作公司哪家好一点,北京租房网站有哪些?
Laravel怎么为数据库表字段添加索引以优化查询
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
如何挑选优质建站一级代理提升网站排名?
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
如何在建站之星网店版论坛获取技术支持?
Laravel Docker环境搭建教程_Laravel Sail使用指南
高端建站如何打造兼具美学与转化的品牌官网?
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】
Laravel如何实现数据库事务?(DB Facade示例)
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
PythonWeb开发入门教程_Flask快速构建Web应用
Laravel Session怎么存储_Laravel Session驱动配置详解
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
魔毅自助建站系统:模板定制与SEO优化一键生成指南
如何快速搭建FTP站点实现文件共享?
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
java ZXing生成二维码及条码实例分享
如何在橙子建站上传落地页?操作指南详解
香港服务器网站卡顿?如何解决网络延迟与负载问题?
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
如何快速搭建高效可靠的建站解决方案?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
网站制作壁纸教程视频,电脑壁纸网站?
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
JavaScript数据类型有哪些_如何准确判断一个变量的类型
Android中AutoCompleteTextView自动提示
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
Laravel怎么连接多个数据库_Laravel多数据库连接配置
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置

