1. 窗口函数基础概念
窗口函数(Window Function)是SQL中一种强大的分析工具,它能够在保留原始行数据的同时,对数据的子集进行计算。与普通聚合函数不同,窗口函数不会将多行合并为一行,而是为每一行返回一个计算结果。
ROW_NUMBER()是最常用的窗口函数之一,它的核心功能是为结果集中的行分配唯一的序号。这个序号从1开始,按照指定的排序规则依次递增。在实际业务场景中,ROW_NUMBER()常用于分页查询、去重操作、排名计算等需求。
窗口函数的基本语法结构包含三个关键部分:
- PARTITION BY:定义数据分组的依据
- ORDER BY:指定排序规则
- 窗口框架(Window Frame):确定计算范围
sql复制ROW_NUMBER() OVER (
[PARTITION BY column1, column2,...]
ORDER BY column3, column4,...
)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ROW_NUMBER()函数深度解析
2.1 基本工作原理
ROW_NUMBER()函数的工作流程可以分为以下几个步骤:
- 首先根据PARTITION BY子句将数据分组(如果指定了PARTITION BY)
- 在每个分组内,按照ORDER BY子句指定的排序规则对行进行排序
- 从1开始,为每一行分配一个连续的唯一序号
- 如果没有指定PARTITION BY,则整个结果集被视为一个分组
注意:ROW_NUMBER()分配的序号完全基于排序结果,不考虑值是否相同。即使两行的排序字段值相同,它们也会获得不同的序号。
2.2 与相似函数的区别
SQL中还有其他几个类似的序号分配函数,它们与ROW_NUMBER()有以下关键区别:
| 函数 | 相同值处理 | 序号连续性 | 典型用途 |
|---|---|---|---|
| ROW_NUMBER() | 不同序号 | 连续 | 精确排序、分页 |
| RANK() | 相同序号,跳过后续 | 可能不连续 | 比赛排名 |
| DENSE_RANK() | 相同序号,不跳过 | 连续 | 成绩分级 |
举例说明:
sql复制SELECT
student_name,
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_results;
3. 高级应用场景
3.1 数据分页实现
ROW_NUMBER()是实现高效分页查询的核心技术。传统LIMIT OFFSET方法在数据量大时性能较差,而基于ROW_NUMBER()的分页可以显著提高查询效率。
sql复制-- 基础分页实现
WITH numbered_rows AS (
SELECT
*,
ROW_NUMBER() OVER(ORDER BY create_tim
