SQL窗口函数实践笔记

好,这个题目非常偏“进阶 SQL + 面试/实战”,我就直接给你一份能抄走用、也能讲给面试官听的《SQL 窗口函数实践笔记》
不灌水,**以“为什么 → 怎么写 → 什么时候用”**为主。


SQL 窗口函数实践笔记(Window Functions)


一、为什么要用窗口函数?

一句话概括:

窗口函数 = 在“不减少行数”的前提下做统计分析

对比一下 👇

传统 GROUP BY 的问题

SELECT dept, AVG(salary)
FROM emp
GROUP BY dept;
  • 会 丢行
  • 不能看到“每个人 + 部门平均值”

窗口函数能做到什么?

SELECT
  name,
  dept,
  salary,
  AVG(salary) OVER (PARTITION BY dept) AS dept_avg
FROM emp;

✅ 行不丢
✅ 统计结果“贴”在每一行上


二、窗口函数的基本语法(核心)

函数名(...) OVER (
  PARTITION BY ...
  ORDER BY ...
  ROWS / RANGE ...
)
子句作用
PARTITION BY分组(逻辑分组,不合并行)
ORDER BY窗口内排序
ROWS / RANGE窗口范围

三、常用窗口函数分类


1️⃣ 聚合类窗口函数

示例:部门平均工资

AVG(salary) OVER (PARTITION BY dept)

常见函数:

  • SUM()
  • AVG()
  • COUNT()
  • MAX()
  • MIN()

📌 区别于 GROUP BY:不合并行


2️⃣ 排名类窗口函数(高频)

ROW_NUMBER(不并列)

ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC)

RANK(并列跳号)

RANK() OVER (ORDER BY score DESC)

DENSE_RANK(并列不跳号)

DENSE_RANK() OVER (ORDER BY score DESC)
分数RANKDENSE_RANK
10011
9022
9022
8043

3️⃣ 偏移函数(分析神器)

LAG / LEAD

LAG(salary, 1) OVER (ORDER BY month)

👉 取“上一行 / 下一行”的值

常见场景

  • 环比
  • 同比
  • 增长率

4️⃣ 分布类函数(了解)

  • NTILE(n):分桶
  • PERCENT_RANK()
  • CUME_DIST()

四、窗口范围(ROWS vs RANGE)

1️⃣ ROWS(基于行)

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  • 精确
  • 推荐使用

2️⃣ RANGE(基于值)

RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  • 可能包含多行
  • 小心重复值

📌 实战建议:优先 ROWS


五、实战案例(直接可用)


1️⃣ 每个部门工资排名 Top 3

SELECT *
FROM (
  SELECT
    name,
    dept,
    salary,
    ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn
  FROM emp
) t
WHERE rn <= 3;

🔥 面试必会


2️⃣ 计算工资环比增长

SELECT
  month,
  salary,
  salary - LAG(salary) OVER (ORDER BY month) AS diff
FROM emp_salary;

3️⃣ 累计求和

SUM(sales) OVER (
  ORDER BY day
  ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS total_sales

4️⃣ 去重保留最新一条

SELECT *
FROM (
  SELECT *,
    ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY update_time DESC) rn
  FROM user_log
) t
WHERE rn = 1;

六、窗口函数执行顺序(面试点)

SQL 执行顺序(简化):

FROM
→ WHERE
→ GROUP BY
→ HAVING
→ SELECT
→ WINDOW FUNCTION
→ ORDER BY

📌 窗口函数 不能写在 WHERE 中


七、性能 & 实战注意点

  • 窗口函数 ≠ 免费
  • PARTITION BY 可能导致排序
  • 大表务必:
    • 控制窗口范围
    • 合理加索引(order by 字段)

八、MySQL / PostgreSQL / Oracle 支持情况

  • MySQL:8.0+
  • PostgreSQL:强(最早支持)
  • Oracle:成熟

九、面试一句话总结

窗口函数用于在不合并结果行的情况下进行排序、排名和统计分析,是分析型 SQL 的核心能力,常用于 TopN、环比、累计值等场景。


十、速记口诀(很有用)

GROUP BY 会合并行,窗口函数不合并;
排名用 ROW_NUMBER,分析用 LAG/LEAD。


如果你愿意,我可以下一步直接帮你:

  • 🔥 SQL 窗口函数面试 10 连问
  • 🔥 MySQL 窗口函数执行计划分析
  • 🔥 窗口函数 vs 子查询 vs Join 对比
  • 🔥 实际业务场景建模(报表 / BI)

你是 数据分析 / 后端开发 / 面试准备 哪个方向?

文章已创建 4298

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部