​​引言:为什么需要窗口函数?​​

在日常数据分析中,我们经常遇到这样的需求:

  • ​“查询每个部门工资最高的员工”​

  • ​“计算每个用户的累计消费金额”​

  • ​“对比当前月份和上个月的销售额”​

如果用普通的 GROUP BY,很难同时保留原始行的细节数据。而 ​​窗口函数(Window Function)​​ 正是为解决这类问题而生!
本文将用 ​​真实案例 + 可视化图表 + 代码实战​​,带你彻底掌握这一利器。


​​一、窗口函数基础​​

​​1. 核心概念​​

窗口函数允许你在 ​​不合并行​​ 的情况下,对数据的“窗口”(分组)进行计算。
它包含三个关键部分:

graph LR A[窗口函数] --> B[PARTITION BY 分组] A --> C[ORDER BY 排序] A --> D[FRAME 范围]

​​2. 与GROUP BY的对比​​

特性

窗口函数

GROUP BY

​是否合并行​

保留所有原始行

合并行

​能否访问上下文​

可以(如前一行的值)

不可以

​典型用途​

排名、累计计算、移动平均

聚合统计(求和、计数等)


​​二、窗口函数实战案例​​

​​案例1:查询每个部门工资最高的员工​​

​​数据表 employees​​

id

name

department

salary

1

张三

技术部

15000

2

李四

技术部

18000

3

王五

销售部

12000

​​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;

​​结果​​

id

name

department

salary

2

李四

技术部

18000

3

王五

销售部

12000


​​案例2:计算用户的累计消费​​

​​数据表 orders​​

user_id

order_date

amount

101

2023-01-01

100

101

2023-01-02

200

102

2023-01-01

50

​​SQL实现​​

SELECT 
  user_id,
  order_date,
  amount,
  SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date) AS cumulative_amount
FROM orders;

​​结果​​

user_id

order_date

amount

cumulative_amount

101

2023-01-01

100

100

101

2023-01-02

200

300

102

2023-01-01

50

50


​​三、窗口函数深度解析​​

​​1. 常用函数分类​​

类型

函数示例

用途

​排序​

ROW_NUMBER(), RANK()

计算行排名

​聚合​

SUM(), AVG()

计算分组内的聚合值

​偏移​

LAG(), LEAD()

访问前一行或后一行的数据

​​2. 关键语法详解​​

FUNCTION() OVER (
  [PARTITION BY 分组列] 
  [ORDER BY 排序列] 
  [ROWS|RANGE 范围]
) AS 别名

​​参数说明​​

  • PARTITION BY:类似 GROUP BY 的分组,但不会合并行。

  • ORDER BY:决定组内数据的排序方式。

  • ROWS/RANGE:控制计算范围(如“最近3行”)。


​​四、思维导图总结​​

mindmap root)窗口函数( 核心功能 ["分组计算不合并行"] ["访问上下文数据"] 常用函数 排序 ["ROW_NUMBER()"] ["RANK()"] 聚合 ["SUM()"] ["AVG()"] 偏移 ["LAG()"] ["LEAD()"] 实战场景 ["分组取TOP N"] ["计算累计值"] ["移动平均"]


​​五、进阶技巧​​

​​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 BYORDER BYFRAME

  • 适用场景:排名、累计计算、移动分析等。

​下一步行动​​:
打开 SQL Fiddle,尝试用窗口函数解决你的业务问题!