窗口函数,SQL进阶分水岭:一行代码解决排名、环比,数据分析效率翻倍!

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDSClaw,2核4GB
RDS AI 助手,专业版
简介: 窗口函数是MySQL 8.0+核心进阶功能,支持在不丢失明细的前提下实现排名、累计、环比等跨行分析。掌握ROW_NUMBER()、RANK()、SUM() OVER等用法,配合PARTITION BY和ORDER BY,可高效解决复杂报表需求,告别低效自连接。

📌 今日关键词:​窗口函数​、排序分析、累计计算、OVER子句、MySQL​ 8.0

前面我们已经掌握了数据库的“骨架”(表结构)、“加速器”(索引)以及“逻辑大师”(游标与存储过程)。但当我们面对复杂的排名、累计、同比环比分析时,传统的聚合函数(GROUP BY)往往显得力不从心——它会把行“压扁”,让我们无法同时看到明细数据和聚合结果。

所以,今天我们解锁SQL进阶路上的分水岭技术——窗口函数​​(Window Function)! ​🎯它就像是给数据库装上了一副“透视眼镜”,让我们在不丢失任何一行明细数据的前提下,进行跨行的统计分析,用一行代码解决排名、累计、环比问题,数据分析效率翻倍!接下来,小学妹就把窗口函数分享给大家,让你少走弯路少踩坑。

一、什么是窗口函数?——数据的“逻辑透视镜”

窗口函数(Window Function),也叫OLAP函数(Online Analytical Processing),它允许我们在结果集的“子集”(即窗口)上进行聚合或计算,而不需要将行折叠成单个输出行。

💡 类比:你有一张全班成绩表。聚合函数就像“全班平均分”,只给你一个数字;窗口函数则能在每一行旁边加一列“全班平均分”,让你知道每个人的分数和平均分的差距,同时保留每个人的详细信息。

🔍窗口函数 vs 聚合函数:

函数类型 结果行数 典型用途
聚合函数 + GROUP BY 减少行数(每组一行) 每个班级的平均分
窗口函数 保持原行数 每行旁边显示班级平均分

二、窗口函数的基本语法

SELECT 列名,       
    窗口函数() OVER (PARTITION BY 分组列 ORDER BY 排序列) AS 别名
FROM 表名;
  • ​窗口函数​:ROW_NUMBER()RANK()SUM()AVG()
  • OVER():定义窗口的大小和顺序
  • PARTITION BY:分组(可选,不加则整个表为一个窗口)
  • ORDER BY:窗口内的排序(重要)

💡 可以把窗口理解为 GROUP BY 的分组,但每一行都留在结果中。

三、三大类窗口函数(新手必学)

  1. 排名函数(最常用)

函数 说明 例子(分数:90,90,80)
ROW_NUMBER() 连续编号,不分先后 1,2,3
RANK() 跳跃排名,相同分数并列 1,1,3
DENSE_RANK() 连续排名,相同分数并列 1,1,2

💻实战:查询每个部门的员工按工资排名

SELECT     
    name,     
    department,     
    salary,    
    ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_rank,    
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_rank,    
    DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_rank
FROM employees;
  1. 聚合函数 + 窗口(累计、移动平均)

支持在窗口中使用 SUMAVGCOUNTMAXMIN

💻实战:计算每个月的累计销售额

SELECT 
    month,
    sales,
    SUM(sales) OVER (ORDER BY month) AS cumulative_sales
FROM sales_data;

💻实战:计算过去3个月的移动平均销售额

SELECT 
    month,
    sales,
    AVG(sales) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM sales_data;

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW 表示“从当前行往前的2行到当前行”,共3行。

  1. 取值函数(高级)

函数 说明
LAG(列名, offset) 取当前行前面第offset行的值
LEAD(列名, offset) 取当前行后面第offset行的值
FIRST_VALUE() / LAST_VALUE() 窗口内第一行/最后一行的值

💻实战:计算每个月的销售额环比增长率

SELECT 
    month,
    sales,
    LAG(sales, 1) OVER (ORDER BY month) AS prev_month_sales,
    (sales - LAG(sales, 1) OVER (ORDER BY month)) / LAG(sales, 1) OVER (ORDER BY month) * 100 AS growth_rate
FROM sales_data;

四、实战案例:学生成绩排名 + 班级对比

假设有 stu_score 表:(id, name, class, score)

🔔需求:

  • 显示每个学生的姓名、班级、分数
  • 显示全校排名(RANK()
  • 显示班级内排名
  • 显示班级最高分(MAX() 窗口)
SELECT 
    name,
    class,
    score,
    RANK() OVER (ORDER BY score DESC) AS school_rank,
    RANK() OVER (PARTITION BY class ORDER BY score DESC) AS class_rank,
    MAX(score) OVER (PARTITION BY class) AS class_max_score
FROM stu_score;

🚩结果示例:

name class score school_rank class_rank class_max_score
小明 1班 98 1 1 98
小红 1班 95 2 2 98
小刚 2班 97 3 1 97

五、窗口函数避坑指南

版本限制:

  • MySQL 5.7 及更早版本不支持窗口函数!
  • 必须使用 MySQL 8.0+。如果你还在用旧版本,建议升级,或者使用复杂的自连接(Self-Join)来模拟,但性能极差。

性能陷阱:

  • 如果不写 PARTITION BY 且数据量巨大,窗口函数会扫描全表进行计算,非常消耗内存。
  • 建议: 尽量配合索引使用,ORDER BY 的列最好有索引。

NULL值处理:

  • 排序函数(如 RANK)遇到 NULL 值时,通常会将其视为最小值,或者导致排序结果不符合预期。
  • 建议: 在计算前使用 WHERE 列名 IS NOT NULL 过滤,或用 COALESCE 处理。

六、今日学习心得

  1. 核心思想​: ​窗口函数​ = 保留明细 + 跨行计算​。
  2. 执行顺序​: 记住它在 SELECT 阶段执行,所以不能直接在 WHERE 中过滤,通常需要嵌套一层查询或使用 CTE。
  3. 版本注意​: 确保你的环境是 MySQL 8.0 或 PostgreSQL 或 SQL Server,老版本 MySQL 玩不转这个。

👋 我是数据库小学妹一个用设计师思维学数据库的转行人。我们一起,把复杂的技术变得简单有趣!💕

本文为个人学习总结,所有示例基于 ​MySQL​ 8.0。如果你的版本低于8.0,部分窗口函数不可用,建议升级或使用其他方式替代。

相关文章
|
8天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
3425 20
|
20天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
17975 60
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
|
1天前
|
SQL 人工智能 弹性计算
阿里云发布 Agentic NDR,威胁检测与响应进入智能体时代
欢迎前往阿里云云防火墙控制台体验!
1156 2
|
4天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
1851 8
|
15天前
|
人工智能 JavaScript Ubuntu
低成本搭建AIP自动化写作系统:Hermes保姆级使用教程,长文和逐步实操贴图
我带着怀疑的态度,深度使用了几天,聚焦微信公众号AIP自动化写作场景,写出来的几篇文章,几乎没有什么修改,至少合乎我本人的意愿,而且排版风格,也越来越完善,同样是起码过得了我自己这一关。 这个其实OpenClaw早可以实现了,但是目前我觉得最大的区别是,Hermes会自主总结提炼,并更新你的写作技能。 相信就冲这一点,就值得一试。 这篇帖子主要就Hermes部署使用,作一个非常详细的介绍,几乎一步一贴图。 关于Hermes,无论你赞成哪种声音,我希望都是你自己动手行动过,发自内心的选择!
3170 29
|
3天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
1476 3
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
|
4天前
|
机器学习/深度学习 缓存 测试技术
DeepSeek-V4开源:百万上下文,Agent能力比肩顶级闭源模型
DeepSeek-V4正式开源!含V4-Pro(1.6T参数)与V4-Flash(284B参数)双版本,均支持百万token上下文。首创混合注意力架构,Agent能力、世界知识与推理性能全面领先开源模型,数学/代码评测比肩顶级闭源模型。
1734 6
|
5天前
|
人工智能 测试技术 API
阿里Qwen3.6-27B正式开源:网友直呼“太牛了”!
阿里云千问3.6系列重磅开源Qwen3.6-27B稠密大模型!官网:https://t.aliyun.com/U/JbblVp 仅270亿参数,编程能力媲美千亿模型,在SWE-bench等权威基准中表现卓越。支持多模态理解、本地部署及OpenClaw等智能体集成,已开放Hugging Face与ModelScope下载。