引言:为什么需要窗口函数?
在日常数据分析中,我们经常遇到这样的需求:
“查询每个部门工资最高的员工”
“计算每个用户的累计消费金额”
“对比当前月份和上个月的销售额”
如果用普通的 GROUP BY
,很难同时保留原始行的细节数据。而 窗口函数(Window Function) 正是为解决这类问题而生!
本文将用 真实案例 + 可视化图表 + 代码实战,带你彻底掌握这一利器。
一、窗口函数基础
1. 核心概念
窗口函数允许你在 不合并行 的情况下,对数据的“窗口”(分组)进行计算。
它包含三个关键部分:
2. 与GROUP BY的对比
二、窗口函数实战案例
案例1:查询每个部门工资最高的员工
数据表 employees
SQL实现
WITH ranked_employees AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rank
FROM employees
)
SELECT id, name, department, salary
FROM ranked_employees
WHERE rank = 1;
结果
案例2:计算用户的累计消费
数据表 orders
SQL实现
SELECT
user_id,
order_date,
amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date) AS cumulative_amount
FROM orders;
结果
三、窗口函数深度解析
1. 常用函数分类
2. 关键语法详解
FUNCTION() OVER (
[PARTITION BY 分组列]
[ORDER BY 排序列]
[ROWS|RANGE 范围]
) AS 别名
参数说明
PARTITION BY
:类似GROUP BY
的分组,但不会合并行。ORDER BY
:决定组内数据的排序方式。ROWS/RANGE
:控制计算范围(如“最近3行”)。
四、思维导图总结
五、进阶技巧
1. 移动平均计算
SELECT
date,
sales,
AVG(sales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM sales_data;
2. 分组对比(与平均值比较)
SELECT
department,
salary,
salary - AVG(salary) OVER (PARTITION BY department) AS diff_from_avg
FROM employees;
六、总结
窗口函数 是 SQL 中处理复杂分析需求的终极工具。
核心三要素:
PARTITION BY
、ORDER BY
、FRAME
。适用场景:排名、累计计算、移动分析等。
下一步行动:
打开 SQL Fiddle,尝试用窗口函数解决你的业务问题!