窗口函数进阶:排名、累计、移动平均一网打尽

简介: 本篇干货分享SQL窗口函数实战:一行代码轻松搞定分组取前三、累计占比、移动平均、同比环比等高频需求,告别冗长易错的子查询。涵盖ROW_NUMBER/RANK/DENSE_RANK、LAG/LEAD、分区排序与性能优化要点,助你高效进阶数据分析!

大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

很多数据分析师朋友问我:分组取前三、算累计占比、做移动平均,以前用子查询和自连接写几十行还容易错,有没有更简单的方法?有,窗口函数一行搞定。

1 名词解释

  • 窗口函数:在一组与当前行相关的行(窗口)上执行计算,不合并行,保留原数据。
  • 分区(PARTITION BY):将数据分组,窗口函数在每个分组内独立计算。
  • 排序(ORDER BY):定义窗口内行的顺序,影响排名、累计等函数的计算结果。
  • 框架(ROWS/RANGE):定义窗口的边界,如 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW

2 实际运用

2.1 三种排名函数

SELECT 
    product_id, category, sales,
    ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) AS rn,
    RANK()       OVER (PARTITION BY category ORDER BY sales DESC) AS rk,
    DENSE_RANK() OVER (PARTITION BY category ORDER BY sales DESC) AS dr
FROM products;
函数 行为 示例(销售额:100,90,90,80)
ROW_NUMBER() 唯一编号,不处理并列 1,2,3,4
RANK() 并列跳号 1,2,2,4
DENSE_RANK() 并列不跳号 1,2,2,3


适用场景​:

  • 分页取数据 → ROW_NUMBER()
  • 比赛排名(允许并列但跳过名次) → RANK()
  • 工资等级(并列不跳过) → DENSE_RANK()

2.2 累计和与累计占比(帕累托分析)

SELECT 
    product, sales,
    SUM(sales) OVER (ORDER BY sales DESC) AS running_total,
    SUM(sales) OVER (ORDER BY sales DESC) / SUM(sales) OVER () AS cum_pct
FROM products;

2.3 移动平均(MA3)

SELECT 
    date, sales,
    AVG(sales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS ma3
FROM daily_sales;

2.4 同比/环比(LAG / LEAD)

SELECT 
    date, sales,
    LAG(sales, 1) OVER (ORDER BY date) AS prev_day_sales,
    (sales / LAG(sales, 1) OVER (ORDER BY date) - 1) * 100 AS growth_rate
FROM daily_sales;

2.5 分组内百分比

SELECT 
    category, product, sales,
    sales / SUM(sales) OVER (PARTITION BY category) AS pct_in_category
FROM products;

3 性能注意事项

  • 窗口函数会在内存或磁盘中创建临时表,大量数据时注意监控 Created_tmp_disk_tables 状态。
  • ORDER BY 会触发排序,如果窗口内不需要排序可以省略 ORDER BY 提升性能。
  • MySQL 8.0及以上才支持窗口函数,低版本需要升级或用替代写法。

4 价值总结

  • 学会窗口函数,你可以将几十行的子查询+自连接改写为一行,代码简洁且性能更优。
  • 窗口函数能解决数据分析中的大部分分组统计、排名、累计计算需求,是SQL进阶的里程碑。
  • 建议先从 ROW_NUMBER() 和 SUM() OVER() 入手,再逐步掌握 RANK()、LAG() 等高级函数。

小耶在手,SQL不愁。

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~

相关文章
|
2月前
|
SQL JavaScript 关系型数据库
SQL改写实战:子查询、CTE、窗口函数性能对比
本文聚焦SQL性能优化,实测对比子查询、CTE与窗口函数在复杂统计、分组排名、递归查询等场景的执行效率。基于MySQL 8.0真实数据(千万级表),揭示窗口函数在“每组取最值”“部门排名”中提速3倍以上,CTE提升可读性与递归能力,而相关子查询易成性能瓶颈。干货满满,避坑必备!
|
2月前
|
安全 Java 数据建模
【Java基础】JDK17:密封类、模式匹配、Record类(附《思维导图》+《面试高频考点清单》)
Java 17作为LTS版本,重磅引入密封类、模式匹配与Record类三大特性:Record简化不可变数据建模,密封类精准控制继承边界,模式匹配(instanceof+switch)提升类型安全与代码简洁性。三者协同可优雅实现代数数据类型,标志着Java迈向更安全、简洁、表达力更强的现代编程语言。
【Java基础】JDK17:密封类、模式匹配、Record类(附《思维导图》+《面试高频考点清单》)
|
20天前
|
存储 固态存储 关系型数据库
从月账单5万到3.5万:云数据库成本优化的完整复盘
上云本应是降本增效,但很多企业上云之后,账单反而越滚越大。实例规格买高了、历史数据堆在SSD上、测试环境没人关、过期快照没清理——每一笔费用都在悄悄累积。本文从云账单的三大“黑洞”出发,拆解云成本失控的根因,给出实例降配、冷热数据分层、僵尸资源清理三条可落地的优化路径,帮助DBA和运维工程师用数据驱动成本优化,让每一分钱都花在刀刃上。
|
2月前
|
存储 缓存 安全
【Java基础】集合框架: ArrayList vs LinkedList 核心区别、扩容机制(附《思维导图》+《面试高频考点清单》)
本文深入解析ArrayList与LinkedList的核心差异:前者基于动态数组,支持O(1)随机访问、尾部增删高效,但中间/头部操作需移动元素;后者基于双向链表,头部/尾部增删为O(1),但随机访问O(n)且内存开销大4–5倍。重点剖析ArrayList的1.5倍扩容机制及CPU缓存优势,澄清“LinkedList更适合队列”等常见误区。
|
1月前
|
存储 人工智能 关系型数据库
湖库一体:2026年数据库架构的“终极答案”还是新瓶装旧酒?
2026年6月,OceanBase发布湖库一体AI数据库,阿里云PolarDB年初已推出AI数据湖库(Lakebase),Databricks也在6月推出了LTAP架构。“湖库一体”成为2026年数据库圈最热的概念之一。本文从湖库一体的概念定义出发,拆解其技术原理,对比“湖仓一体”与“湖库一体”的差异,分析三大厂商的落地路径,并讨论这一趋势对DBA和架构师的现实意义。
|
2月前
|
人工智能 缓存 自然语言处理
阿里云AI模型节省计划是什么?优势及优惠折扣有哪些?购买及使用指引
阿里云百炼推出AI大模型节省计划,含通用型(最高5.3折、覆盖全部直供模型)、专用型(图像/语音/向量等)及资源包三类方案,支持多地域、自动抵扣,助力企业降本增效。阿里云百炼AI大模型官网:https://t.aliyun.com/U/fPVHqY
|
3月前
|
关系型数据库 MySQL 测试技术
JOIN、IN、EXISTS谁最快?实测三种写法性能差异与执行计划深度剖析
本文用MySQL 8.0实测拆解`IN`/`EXISTS`/`JOIN`子查询性能:从执行计划、半连接优化、临时表开销等底层原理出发,结合10万+100万数据实测(`EXISTS`最快95ms),给出三条选型铁律——告别盲从“最佳实践”,只选最适配业务与数据的写法!
|
2月前
|
SQL 存储 关系型数据库
覆盖索引:让你的查询直接从索引返回,彻底告别回表
覆盖索引是SQL优化中性价比较高的技巧,让查询直接从索引返回所需列,避免回表操作。本文解释覆盖索引的原理,通过EXPLAIN的“Using index”判断是否生效。结合复合索引设计、深分页优化(延迟关联)等场景,给出覆盖索引的使用方法和注意事项。用好覆盖索引,不改SQL逻辑,仅调整索引设计即可显著提升查询性能。
|
3月前
|
SQL 关系型数据库 MySQL
MySQL慢查询诊断实战:从10秒到0.1秒,我的5步排障法
数据库小学妹分享慢查询优化实战:从10秒降至0.08秒!详解「发现→收集→分析→优化→验证」5步排障法,覆盖慢日志配置、EXPLAIN进阶、索引失效场景、JOIN与分页优化等核心技巧,附真实案例与速查表。
|
2月前
|
SQL 人工智能 自然语言处理
Vibe Coding 是什么?当“感觉编程”遇上数据库
Vibe Coding是2026年编程圈最火的概念之一,指开发者通过自然语言描述“感觉”或“意图”,由AI自动生成代码、调试、优化。本文从Vibe Coding的起源讲起,分析它如何改变数据库开发方式:从手写SQL到自然语言查询、从人工调索引到AI推荐、从经验运维到智能诊断。探讨这项趋势对DBA职业的影响,并给出拥抱变化的实用建议。技术会变,但人的判断力、审美和业务理解才是长期竞争力。

热门文章

最新文章