MySQL 中 ROW_NUMBER() 函数详解

MySQL 中 ROW_NUMBER() 函数详解

ROW_NUMBER() 是 SQL 窗口函数中的一种,用于为查询结果集中的每一行分配一个​​唯一的连续序号​​。与 RANK() 和 DENSE_RANK() 不同,ROW_NUMBER() 不会处理重复值,即使排序字段值相同,也会严格按行顺序递增编号。

一、基础语法
ROW_NUMBER() OVER ([PARTITION BY 分组字段]ORDER BY 排序字段 [ASC|DESC]
)
  • ​PARTITION BY​​:按指定字段分组,每组内重新从1开始编号。
  • ​ORDER BY​​:决定排序逻辑,影响行号的分配顺序。

二、核心特点
​特性​​说明​
唯一性每行序号严格递增,不重复(即使排序字段值相同)
灵活性可结合分组(PARTITION BY)实现复杂场景
兼容性MySQL 8.0+ 原生支持,低版本需用变量模拟
性能影响未优化时可能导致全表扫描,需合理使用索引

三、典型应用场景
1. 数据分页查询
-- 查询第3页数据(每页10条)
WITH paged_data AS (SELECT id, name, ROW_NUMBER() OVER (ORDER BY id) AS row_numFROM users
)
SELECT * 
FROM paged_data 
WHERE row_num BETWEEN 21 AND 30;
2. 删除重复数据
-- 保留最新记录(假设 create_time 为时间戳)
DELETE FROM orders
WHERE (id, product_id) IN (SELECT id, product_id FROM (SELECT id, product_id,ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY create_time DESC) AS rnFROM orders) t WHERE rn > 1  -- 删除重复项,保留最新一条
);
3. 分组取Top N记录
-- 获取每个部门薪资前3名
SELECT *
FROM (SELECT name, department, salary,ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rankFROM employees
) ranked
WHERE dept_rank <= 3;
4. 生成唯一流水号
-- 按日期生成订单流水号(格式:YYYYMMDD-0001)
SELECT order_id,CONCAT(DATE_FORMAT(create_time, '%Y%m%d'), '-', LPAD(ROW_NUMBER() OVER (PARTITION BY DATE(create_time) ORDER BY create_time), 4, '0')) AS serial_num
FROM orders;

四、与其他排序函数对比
函数重复值处理示例结果(排序字段值相同)
ROW_NUMBER()强制分配不同序号1, 2, 3, 4
RANK()相同值共享排名,后续跳过序号1, 1, 3, 4
DENSE_RANK()相同值共享排名,后续连续递增1, 1, 2, 3
-- 对比三种函数
SELECT score,ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num,RANK() OVER (ORDER BY score DESC) AS rank,DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM exam_scores;

五、性能优化技巧
1. 索引设计
  • 为 PARTITION BY 和 ORDER BY 涉及的字段创建联合索引:
     
    CREATE INDEX idx_dept_salary ON employees(department, salary DESC);

2. 减少计算范围
 
-- 仅处理2023年数据
SELECT *
FROM (SELECT order_id, amount,ROW_NUMBER() OVER (ORDER BY amount DESC) AS rnFROM ordersWHERE YEAR(order_date) = 2023  -- 先过滤再排序
) t
WHERE rn <= 100;
3. 避免嵌套查询
-- 优化前(性能差)
SELECT * FROM (SELECT *, ROW_NUMBER() OVER (...) AS rnFROM large_table
) t WHERE rn <= 100;-- 优化后(直接使用LIMIT,若逻辑允许)
SELECT *, ROW_NUMBER() OVER (...) AS rn
FROM large_table
ORDER BY ...
LIMIT 100;

六、MySQL低版本兼容方案(5.7及以下)
使用会话变量模拟 ROW_NUMBER()
 
-- 按部门分组排序
SELECT department, name, salary,@row_num := IF(@current_dept = department, @row_num + 1, 1) AS row_num,@current_dept := department AS dummy
FROM employees
ORDER BY department, salary DESC;

七、常见错误与排查
1. 错误:序号不符合预期
  • ​原因​​:未正确指定 ORDER BY 或 PARTITION BY
  • ​解决​​:检查排序字段是否明确,分组条件是否合理
2. 错误:性能低下
  • ​原因​​:未使用索引导致全表扫描
  • ​解决​​:使用 EXPLAIN 分析执行计划,添加必要索引
3. 错误:结果集为空
  • ​原因​​:外层查询条件与子查询中的 WHERE 冲突
  • ​解决​​:验证过滤条件逻辑

八、最佳实践
  1. ​明确排序规则​​:始终显式指定 ORDER BY 的排序方向(ASC/DESC)
  2. ​慎用全局排序​​:避免无 PARTITION BY 的大数据集操作
  3. ​监控内存使用​​:窗口函数可能消耗大量临时内存
  4. ​版本验证​​:生产环境确认 MySQL 版本 >= 8.0
  5. ​结合 CTE 使用​​:提高复杂查询的可读性
    WITH ranked_products AS (SELECT product_id,ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) AS rnFROM products
    )
    SELECT * FROM ranked_products WHERE rn = 1;


​总结​​:ROW_NUMBER() 是处理行级序号分配的利器,特别适合需要精确控制行顺序的场景。合理使用可显著简化分页、去重、Top N查询等操作,但需注意其对性能的影响,尤其在处理海量数据时需结合索引优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81814.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode百题斩-二叉树

二叉树作为经典面试系列&#xff0c;那么当然要来看看。总计14道题&#xff0c;包含大量的简单题&#xff0c;说明这确实是个比较基础的专题。快速过快速过。 先构造一个二叉树数据结构。 public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode…

Asp.Net Core 如何配置在Swagger中带JWT报文头

文章目录 前言一、配置方法二、使用1、运行应用程序并导航到 /swagger2、点击右上角的 Authorize 按钮。3、输入 JWT 令牌&#xff0c;格式为 Bearer your_jwt_token。4、后续请求将自动携带 Authorization 头。 三、注意事项总结 前言 配置Swagger支持JWT 一、配置方法 在 …

MySQL 定时逻辑备份

文章目录 配置密码编写备份脚本配置权限定时任务配置检查效果如果不想保留明文密码手工配置备份密码修改备份命令 配置密码 cat >> /root/.my.cnf <<"EOF" [client] userroot passwordYourPassword EOF编写备份脚本 cat > /usr/local/bin/mysql_dum…

在qt中使用c++实现与Twincat3 PLC变量通信

这是一个只针对新手的教程&#xff0c;下载安装就不说了&#xff0c;我下的是TC31-Full-Setup.3.1.4024.66.exe是这个版本&#xff0c;其他版本应该问题不大。 先创建一个项目 选中SYSTEM&#xff0c;在右侧点击Choose Target&#xff08;接下来界面跟我不一样没关系&#xf…

云原生微服务devops项目管理英文表述详解

文章目录 1.云原生CNCF trail map云原生技术栈路线图 2. 微服务单体应用与微服务应用架构区别GraphQLKey differences: GraphQL and REST 3.容器化&编排dockerKubernetesContainers and ContainerizationContainer Basics 4. DevOps & CI/CDTerms and Definitions 5.Ag…

pyside 使用pyinstaller导出exe(含ui文件)

第一步&#xff1a;首先确保安装好pyinstall&#xff0c;终端运行 pyinstaller -w main.py 生成两个文件夹 打开exe文件报错&#xff0c;问题是ui文件找不到 第二步&#xff1a;将ui文件复制到exe所在文件夹&#xff0c;打开成功 ![在这里插入图片描述](https://i-blog.csdni…

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器 js 代码 其他地方用直接导入js getCurrentUserId 这是自己后端获取 域账号地址 我是成功返回200 //true普通浏览器 fasle 无痕浏览器 export const checkBrowserMode async () > {try {const response a…

HTML 计算网页的PPI

HTML 计算网页的PPI vscode上安装live server插件&#xff0c;可以实时看网页预览 有个疑问&#xff1a; 鸿蒙density是按照类别写死的吗&#xff0c;手机520dpi 折叠屏426dpi 平板360dpi <html lang"en" data - overlayscrollbars - initialize><header&…

华为OD机试真题——Boss的收入(分销网络提成计算)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

<el-date-picker>组件传参时,选中时间和传参偏差8小时

遇到一个bug&#xff0c;不仔细看&#xff0c;都不一定能发现&#xff0c;bug描述&#xff1a;我们有一个搜索框&#xff0c;里面有一个时间选择器&#xff0c;当我使用<el-date-picker>时&#xff0c;我发现当我选择时分秒之后&#xff0c;显示都正常&#xff0c;但是当…

uni-app开发特殊社交APP

uni-app开发特殊社交APP 目录 1.展示APP功能 2.展示项目结构 3.关于我的GitHub 引言 博主最近自己在GitHub上面上传了一个关于社交软件的项目&#xff08;该项目早已开发完毕&#xff09;, 这个社交软件比较特殊, 被称之为blind-date&#xff0c; blind-date 是基于 uni-…

深入研究Azure 容器网络接口 (CNI) overlay

启用cni overlay 在通过portal创建aks的时候,在networking配置上,选中下面的选项即可启用。 通过CLI创建AKS 要创建具有 CNI 覆盖网络的 AKS 群集,需要在创建群集时指定 --network-plugin azure 和 --network-plugin-mode 覆盖选项。 还需要指定 --pod-cidr 选项来定义群…

Docker 部署项目

使用 Docker 部署项目是一个很好的选择&#xff0c;可以避免服务器环境不兼容的问题&#xff0c;并且能够实现一致性和可移植性。我会给你一个详细的步骤&#xff0c;帮你从零开始理解 Docker&#xff0c;最终在服务器上部署 Roop 项目。 1. 安装 Docker 首先&#xff0c;你需…

excel表格记账 : 操作单元格进行加减乘除 | Excel中Evaluate函数

文章目录 引用I 基础求和∑II Excel中Evaluate函数基于字符串表达式进行计算用法案例 :基于Evaluate实现汇率计算利润知识扩展在单元格内的换行选择整列单元格引用 需求: 基于汇率计算利润,调整金额以及进汇率和出汇率自动算出利润,已经统计总利润。 基于Evaluate实现汇率计…

vue+ts+TinyEditor 是基于 Quill 2.0 开发的富文本编辑器,提供丰富的扩展功能,适用于现代 Web 开发的完整安装使用教程

简介 TinyEditor 是基于 Quill 2.0 开发的富文本编辑器&#xff0c;提供丰富的扩展功能&#xff0c;适用于现代 Web 开发。具备模块化设计、轻量级架构和高度可定制化特性&#xff0c;支持多种插件扩展&#xff0c;满足不同场景需求。 核心特性 基于 Quill 2.0 的现代化架构模…

matlab实现激光腔长计算满足热透镜效应

激光腔长计算与热透镜效应补偿 在全固态激光器中&#xff0c;热透镜效应是一个重要的问题&#xff0c;因为它会影响激光的光束质量和输出功率。以下是如何计算激光腔长并考虑热透镜效应的方法&#xff0c;以及一些补偿技术。 1. 激光腔长计算 激光腔长的计算需要考虑激光晶体…

Science Robotics 具身智能驱动的空中物理交互新范式:结合形态和传感,与非结构化环境进行稳健交互

随着科技的飞速发展&#xff0c;无人机技术已从单纯的远程感知扩展到与环境的物理交互领域&#xff0c;为可持续发展目标的实现提供了新的可能性。传统的空中物理交互方法依赖于复杂的控制策略和精确的环境建模&#xff0c;尽管能够实现高精度操作&#xff0c;但其在非结构化自…

图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析

现代信息检索系统和搜索引擎普遍采用两阶段检索架构&#xff0c;在人工智能应用中也被称为检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;。在初始检索阶段&#xff0c;系统采用高效的检索方法&#xff0c;包括词汇检索算法&#xff08;如BM25&…

List 源码翻译

List 源码翻译-jdk1.8 翻译来自 AI 大模型。 全部源码翻译下载 /** 版权所有 (c) 1997, 2014, Oracle 和/或其附属公司。保留所有权利。* ORACLE 专有/机密。使用受许可条款约束。*********************/package java.util;import java.util.function.UnaryOperator;/*** 有序…