在现代数据处理中,窗口函数(Window Functions) 是提升 SQL 表达力和执行效率的重要工具。SQL Server 自 2005 开始引入基础窗口函数,自 2012 起逐步完善功能,至今已成为数据开发与分析的必备技能。
本文将围绕以下几个部分展开:
-
一、窗口函数基本概念
-
二、窗口函数的语法结构
-
三、常用窗口函数分类及示例
-
四、典型应用场景
-
五、性能注意事项与优化建议
一、窗口函数基本概念
窗口函数 是一种特殊的聚合函数,它与普通聚合函数(如 SUM()
、COUNT()
)不同,不会合并多行变为一行,而是为结果集中的每一行,在定义的“窗口”内执行聚合、排序、排名等计算。
通俗理解:
窗口函数 = 按照某种方式“分组” + “排序”后,对“每行”计算某种聚合值。
二、窗口函数语法结构
<函数名>(<表达式>) OVER (
[PARTITION BY <分组列>]
[ORDER BY <排序列>]
[ROWS|RANGE BETWEEN <起点> AND <终点>]
)
-
OVER():定义窗口范围
-
PARTITION BY:按某列分区,相当于“组”
-
ORDER BY:在组内排序(部分函数可选)
-
ROWS BETWEEN:进一步限制窗口边界(仅对某些函数有效,如
SUM()
)
三、常用窗口函数分类及示例
1. 排名类函数(Ranking Functions)
函数 | 说明 |
---|---|
ROW_NUMBER() | 分组内唯一排序编号 |
RANK() | 相同值排名相同,存在跳跃 |
DENSE_RANK() | 相同值排名相同,无跳跃 |
NTILE(n) | 将排序后的结果划分为 n 个桶 |
示例:统计每个部门员工薪资排名
SELECT emp_id, dept_id, salary,
RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS salary_rank
FROM employees;
2. 聚合类函数(Aggregate Window Functions)
支持:SUM()
、AVG()
、COUNT()
、MIN()
、MAX()
示例:计算每个用户最近12个月累计消费金额
SELECT user_id, month, amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY month
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) AS rolling_sum
FROM orders;
3. 偏移类函数(Offset Functions)
函数 | 说明 |
---|---|
LAG(expr) | 获取前一行值 |
LEAD(expr) | 获取后一行值 |
FIRST_VALUE(expr) | 分组内第一个值 |
LAST_VALUE(expr) | 分组内最后一个值(需结合 ROWS 定义) |
示例:比较当前与上月销售额差异
SELECT store_id, month, sales,
sales - LAG(sales) OVER (PARTITION BY store_id ORDER BY month) AS diff
FROM store_sales;
四、窗口函数的典型使用场景
1. 分组内排序和排名
-
统计每类商品的销售排名
-
为每位员工生成组内编号(如:前5名)
2. 分组内的累计值
-
滚动累计销量、累计成交金额
-
积分系统中的时间段累加
3. 前后行比较
-
分析前一天与当天的数值差异(如股价涨跌)
-
营收连续增长分析
4. 找出组内特定记录
-
每组中的第一条或最后一条记录(如用户首次购买)
-
每个项目最近一次状态变更
5. Top-N 分组筛选
使用
ROW_NUMBER()
与子查询配合完成
WITH RankedOrders AS (
SELECT customer_id, order_id, amount,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY amount DESC) AS rn
FROM orders
)
SELECT * FROM RankedOrders WHERE rn <= 3;
6. 同比与环比分析
适用于电商、销售等时间序列分析
五、性能注意事项与优化建议
✅ 建议
-
对
PARTITION BY
与ORDER BY
涉及的字段添加索引 -
控制
OVER()
中的窗口范围,避免UNBOUNDED
带来的全表计算 -
使用临时表或 CTE 缓存窗口结果,避免重复计算
❌ 避免
-
在大数据集上使用未分区的窗口函数
-
在主查询中过度嵌套窗口函数,影响可读性和执行计划
结语
SQL Server 窗口函数作为现代 SQL 编程的核心工具之一,提升了分析场景下的表达力与性能效率。它不仅能减少业务逻辑在中间层实现的复杂度,还能用更简洁的 SQL 实现更复杂的需求。对于报表、BI、风控、日志分析等高频数据处理任务,熟练掌握窗口函数是构建高效数据逻辑的关键。