SQL中的窗口函数能够在查询结果集的基础上,对数据进行分组内的计算分析,不会改变原结果集的行数,非常适合处理排名、累计值、前后行对比等场景,结合SELECT语句使用时可以大幅简化复杂查询的逻辑。

窗口函数的基本语法结构
SELECT结合窗口函数使用时,核心结构是在SELECT的字段列表中加入窗口函数表达式,窗口函数通过OVER子句来定义窗口范围,基本语法如下:
SELECT
列1,
列2,
窗口函数(参数) OVER (
[PARTITION BY 分区列]
[ORDER BY 排序列 [ASC|DESC]]
[ROWS|RANGE 窗口框架]
) AS 别名
FROM 表名;
其中OVER子句里的三个部分都是可选的,根据实际需求选择使用即可。
PARTITION BY 分区的作用
PARTITION BY用来将数据按照指定列分成多个独立的分组,窗口函数会在每个分组内独立计算,效果类似GROUP BY但不会合并行。比如我们需要统计每个部门内的员工薪资排名,就可以用部门列作为分区条件。
ORDER BY 排序的作用
ORDER BY用来指定每个分区内数据的排序规则,很多排名类窗口函数必须依赖排序规则才能正确计算结果,比如ROW_NUMBER()、RANK()等函数都需要明确排序字段。
常用的窗口函数分类
结合SELECT使用的窗口函数主要分为三类,不同类型的函数适用场景有所区别。
排名类窗口函数
这类函数用来在分区内对数据进行排名,常见的有三个:
ROW_NUMBER():给每一行分配一个唯一的连续序号,即使排序值相同也会分配不同的序号RANK():排序值相同时会分配相同的排名,下一个排名会跳过重复的数量DENSE_RANK():排序值相同时分配相同排名,下一个排名不会跳过重复的数量
以下是一个统计员工部门内薪资排名的示例:
SELECT
emp_id,
dept_name,
salary,
ROW_NUMBER() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS row_num,
RANK() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS rank_val,
DENSE_RANK() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS dense_rank_val
FROM employee;
聚合类窗口函数
普通的聚合函数如SUM()、AVG()、COUNT()等,加上OVER子句之后就可以作为窗口函数使用,用来计算每个分区内的累计值、平均值等,不会合并行。
比如统计每个员工的薪资以及所在部门的平均薪资:
SELECT
emp_id,
dept_name,
salary,
AVG(salary) OVER (PARTITION BY dept_name) AS dept_avg_salary
FROM employee;
取值类窗口函数
这类函数用来获取当前行前后指定行的数据,常见的有LAG()和LEAD():
LAG(列, 偏移量, 默认值):获取当前行之前指定偏移量的行的列值LEAD(列, 偏移量, 默认值):获取当前行之后指定偏移量的行的列值
示例为获取每个员工的上一个入职员工的薪资:
SELECT
emp_id,
hire_date,
salary,
LAG(salary, 1, 0) OVER (ORDER BY hire_date) AS prev_emp_salary
FROM employee;
窗口框架的使用
在OVER子句中还可以通过ROWS或RANGE指定窗口框架,用来限定每个分区内参与计算的数据行范围,常见的用法有:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:从分区第一行到当前行ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING:当前行前3行到前1行ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING:从当前行到分区最后一行
比如计算累计薪资的示例:
SELECT
emp_id,
hire_date,
salary,
SUM(salary) OVER (
ORDER BY hire_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS cumulative_salary
FROM employee;
使用注意事项
在使用SELECT结合窗口函数时,需要注意以下几点:
- 窗口函数只能出现在SELECT子句和ORDER BY子句中,不能出现在WHERE、GROUP BY、HAVING子句里
- 如果同时使用了GROUP BY,窗口函数会在GROUP BY聚合之后的结果集上进行计算
- 不同数据库对窗口函数的支持程度略有差异,比如MySQL从8.0版本开始才支持窗口函数,使用前需要确认数据库版本
窗口函数的执行顺序在WHERE、GROUP BY、HAVING之后,在SELECT的普通字段计算之后、ORDER BY之前,理解执行顺序有助于避免逻辑错误。
SQLSELECT窗口函数over_clauserank修改时间:2026-06-20 15:30:28