发布时间:2026/9/1 7:46:08
使用窗口函数 在复杂数据分析、报表统计、排名计算等场景中经常使用。窗口函数是 SQL 中非常强大的功能可以在不改变行数的情况下对每一行进行计算同时保留原始数据。下面我从核心概念、语法结构、常用函数分类、实战案例、性能优化几个维度来系统说明。 窗口函数是什么窗口函数是在一个“窗口”记录集合上执行计算但不会将多行合并为一行每行都保留自己的身份同时可以获得聚合结果。对比聚合函数特性普通聚合函数窗口函数行数变化多行 → 一行行数不变典型函数SUM(),AVG(),COUNT()ROW_NUMBER(),RANK(),SUM() OVER()使用场景汇总统计排名、累计、移动平均、环比同比-- ❌ 聚合函数多行合并成一行SELECTdepartment,AVG(salary)FROMemployeesGROUPBYdepartment;-- ✅ 窗口函数每行保留同时显示部门平均工资SELECTname,department,salary,AVG(salary)OVER(PARTITIONBYdepartment)ASdept_avgFROMemployees; 语法结构窗口函数OVER([PARTITIONBY分区字段]-- 可选将数据分组[ORDERBY排序字段]-- 可选定义排序影响排名类函数[ROWS/RANGE 窗口范围]-- 可选定义帧滑动窗口)三种核心组成部分窗口函数PARTITION BY分组ORDER BY排序窗口帧滑动范围计算每个部门内按工资排序取前三行/累计到当前 窗口函数分类1️⃣ 排名类函数函数说明示例结果ROW_NUMBER()连续排名不跳号1,2,3,4RANK()跳跃排名相同值同排名1,2,2,4DENSE_RANK()密集排名相同值同排名连续1,2,2,3NTILE(n)分成 n 组1,1,2,2,3,3SELECTname,department,salary,ROW_NUMBER()OVER(ORDERBYsalaryDESC)ASrow_num,RANK()OVER(ORDERBYsalaryDESC)ASrank_num,DENSE_RANK()OVER(ORDERBYsalaryDESC)ASdense_rank_num,NTILE(4)OVER(ORDERBYsalaryDESC)ASquartileFROMemployees;结果示例name | department | salary | row_num | rank_num | dense_rank_num | quartile -------|------------|--------|---------|----------|----------------|---------- 张三 | 技术部 | 50000 | 1 | 1 | 1 | 1 李四 | 技术部 | 45000 | 2 | 2 | 2 | 1 王五 | 销售部 | 45000 | 3 | 2 | 2 | 2 赵六 | 销售部 | 40000 | 4 | 4 | 3 | 22️⃣ 聚合类窗口函数在窗口上使用聚合函数相当于“移动汇总”或“分组汇总但不合并行”。函数说明SUM() OVER()累计求和AVG() OVER()移动平均COUNT() OVER()累计计数MAX() / MIN() OVER()窗口内最大/最小值-- 累计销售额按日期SELECTorder_date,amount,SUM(amount)OVER(ORDERBYorder_date)AScumulative_amount,AVG(amount)OVER(ORDERBYorder_dateROWSBETWEEN6PRECEDINGANDCURRENTROW)ASma_7dFROMorders;3️⃣ 取值类窗口函数获取窗口内指定位置的值。函数说明LAG(column, n)获取当前行前第 n 行的值LEAD(column, n)获取当前行后第 n 行的值FIRST_VALUE(column)窗口内第一行的值LAST_VALUE(column)窗口内最后一行的值NTH_VALUE(column, n)窗口内第 n 行的值-- 环比增长计算SELECTorder_date,amount,LAG(amount,1)OVER(ORDERBYorder_date)ASprev_day_amount,(amount-LAG(amount,1)OVER(ORDERBYorder_date))/LAG(amount,1)OVER(ORDERBYorder_date)*100ASgrowth_rate_pctFROMdaily_sales; 实战案例案例 1员工工资排名部门内-- 需求查询每个部门工资前 3 名的员工WITHranked_employeesAS(SELECTname,department,salary,DENSE_RANK()OVER(PARTITIONBYdepartmentORDERBYsalaryDESC)ASrank_in_deptFROMemployees)SELECT*FROMranked_employeesWHERErank_in_dept3;案例 2用户购买累计金额时间序列-- 需求计算每个用户的累计消费金额SELECTuser_id,order_date,amount,SUM(amount)OVER(PARTITIONBYuser_idORDERBYorder_dateROWSBETWEENUNBOUNDEDPRECEDINGANDCURRENTROW)AScumulative_amountFROMorders;案例 37 日移动平均平滑曲线-- 需求计算每日销售额的 7 日移动平均SELECTorder_date,daily_amount,AVG(daily_amount)OVER(ORDERBYorder_dateROWSBETWEEN6PRECEDINGANDCURRENTROW)ASma_7daysFROMdaily_sales;案例 4同比环比计算-- 需求计算每月销售额的环比和同比增长WITHmonthly_salesAS(SELECTDATE_FORMAT(order_date,%Y-%m)ASmonth,SUM(amount)AStotal_amountFROMordersGROUPBYDATE_FORMAT(order_date,%Y-%m))SELECTmonth,total_amount,LAG(total_amount,1)OVER(ORDERBYmonth)ASprev_month_amount,(total_amount-LAG(total_amount,1)OVER(ORDERBYmonth))/LAG(total_amount,1)OVER(ORDERBYmonth)*100ASmom_growth,LAG(total_amount,12)OVER(ORDERBYmonth)ASprev_year_amount,(total_amount-LAG(total_amount,12)OVER(ORDERBYmonth))/LAG(total_amount,12)OVER(ORDERBYmonth)*100ASyoy_growthFROMmonthly_sales;案例 5填充空值使用 LAG/LEAD-- 需求将 NULL 值填充为前一个非 NULL 值SELECTdate,original_value,COALESCE(original_value,LAG(original_value)OVER(ORDERBYdate))ASfilled_valueFROMincomplete_data; 窗口帧Frame详解窗口帧定义了滑动窗口的范围是高级窗口函数的关键。语法{ROWS|RANGE }BETWEENframe_startANDframe_end-- frame_start 可以是UNBOUNDEDPRECEDING-- 从分区第一行开始NPRECEDING-- 当前行前 N 行CURRENTROW-- 当前行-- frame_end 可以是CURRENTROW-- 到当前行NFOLLOWING-- 当前行后 N 行UNBOUNDEDFOLLOWING-- 到分区最后一行常见窗口帧模式模式写法用途累计到当前ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW累计求和移动窗口ROWS BETWEEN 6 PRECEDING AND CURRENT ROW7 日移动平均中心滑动ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING平滑算法到末尾ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING剩余累计-- 累计求和从开始到当前SUM(amount)OVER(ORDERBYdateROWSBETWEENUNBOUNDEDPRECEDINGANDCURRENTROW)-- 7日移动平均AVG(amount)OVER(ORDERBYdateROWSBETWEEN6PRECEDINGANDCURRENTROW)-- 未来3天预测基准AVG(amount)OVER(ORDERBYdateROWSBETWEENCURRENTROWAND3FOLLOWING) 不同数据库的差异特性MySQL 8.0PostgreSQLSQL ServerOracle窗口函数支持✅ 完整✅ 完整✅ 完整✅ 完整窗口帧 ROWS/RANGE✅✅✅✅PERCENT_RANK✅✅✅✅窗口函数在 UPDATE 中❌✅✅✅命名窗口❌✅✅✅MySQL 8.0 前的替代方案使用变量-- MySQL 5.7 模拟 ROW_NUMBER()SELECTname,salary,row_num:row_num1ASrow_numFROMemployees,(SELECTrow_num:0)rORDERBYsalaryDESC;⚡ 性能优化建议1. 合理使用 PARTITION BY-- ✅ 好分区字段有索引ROW_NUMBER()OVER(PARTITIONBYdepartment_idORDERBYsalaryDESC)-- ❌ 差分区过多或分区字段无索引可能导致大量排序2. 减少不必要的窗口函数-- ❌ 同一窗口重复计算SELECTROW_NUMBER()OVER(ORDERBYsalary)ASrn1,RANK()OVER(ORDERBYsalary)ASrn2FROMemployees;-- ✅ 使用命名窗口部分数据库支持SELECTROW_NUMBER()OVERwASrn1,RANK()OVERwASrn2FROMemployees WINDOW wAS(ORDERBYsalary);3. 使用索引优化-- 窗口函数需要排序创建相应索引CREATEINDEXidx_dept_salaryONemployees(department_id,salaryDESC);4. 避免大窗口下的 ROWS BETWEEN-- 大表避免使用过大的窗口范围-- ROWS BETWEEN 1000 PRECEDING AND CURRENT ROW 可能很慢 实际业务场景场景窗口函数方案排行榜ROW_NUMBER() OVER (ORDER BY score DESC)分组 Top NROW_NUMBER() OVER (PARTITION BY category ORDER BY score DESC)累计统计SUM(amount) OVER (ORDER BY date)环比/同比LAG(amount) OVER (ORDER BY date)移动平均AVG(amount) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)去重保留最新ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)用户行为序列LAG(page) OVER (PARTITION BY session_id ORDER BY event_time) 总结问题答案窗口函数是什么在保持行数不变的情况下对每一行进行窗口内计算核心语法是什么函数() OVER (PARTITION BY ... ORDER BY ... 窗口帧)什么时候用排名、累计、移动平均、环比同比、分组 Top N与 GROUP BY 的区别GROUP BY 合并行窗口函数保留行性能如何比子查询/自连接快但需要合理使用索引

相关新闻

2026/9/1 7:46:08

《雾雾恋综》本地大模型驱动的剧本文案生产线搭建指南

《雾雾恋综》这个项目,第一眼看上去更像一部网文或者短剧选题:双女主、恋综、悬念感。但真正让我感兴趣的是,它能不能不再靠人工逐段憋稿,而是变成一条可由本地大模型驱动的剧本文案生产线。这篇文章就围绕这个题材,拆…

2026/9/1 7:46:08

基于AT89C51与Proteus仿真的多功能电子琴设计与实现

简介:本资源是一套基于AT89C51单片机的C语言多功能电子琴系统完整开发包,面向嵌入式初学者、单片机课程设计学生及Proteus仿真爱好者,解决从硬件建模、音阶生成到人机交互实现的一体化实践难题。压缩包共23个文件,含4个C源码&…

2026/9/1 7:46:08

COC跑团熟肉制作全指南:从音轨提取到硬字幕压制

说到 COC 跑团视频里的“熟肉”,很多观众的第一印象是字幕菌真伟大,第二印象可能就是:这个视频怎么还不更新?实际做过熟肉的人才会明白,最折磨人的往往不是翻译本身,而是从生肉到熟肉这条工具链上随时可能冒…

2026/9/1 7:56:09

用UC3846设计36W反激式开关电源

简介:本资源是一套面向电源设计初学者与电子工程师的完整反激式AC-DC隔离电源开发资料,聚焦小功率12V/3A适配器级应用,解决基于UC3846芯片实现稳定、高效反激拓扑设计的核心工程问题。压缩包共30个文件,含原理图(.SchD…

2026/9/1 7:56:09

DeepSeek Harness vs Claude Code:AI开发工具链实测对比与选型指南

在实际 AI 开发工具链的选型中,开发者常常面临一个核心问题:是选择功能全面、生态成熟的商业工具,还是拥抱开源、可深度定制的新兴方案。最近,DeepSeek 推出的 Harness 工具链与 Anthropic 的 Claude Code 在开发者社区中引发了广…

2026/9/1 7:56:09

基于STM32F103与OV7670的车牌识别系统:从图像采集到OpenCV识别

简介:基于STM32F103与OV7670的车牌识别系统设计,是一份面向嵌入式方向毕业设计的完整方案,适合高校学生、嵌入式初学者及智能交通项目开发者参考。项目以STM32F103为控制核心,通过OV7670图像传感器采集车辆图像,系统性…

2026/9/1 7:56:09

QT串口通信数据分包/半包问题解析与缓冲区拼接方案

简介:针对QT串口通信中常见的数据分包与接收不完整问题,这份小型示例工程提供了可直接参考的解决思路与实现代码。资源面向嵌入式、物联网及桌面端串口调试开发者,重点演示基于QSerialPort的异步接收、全局缓冲区拼接以及包头包尾识别等组合策…

2026/9/1 7:51:09

A7105 2.4G无线收发芯片:从SPI寄存器配置到收发例程全攻略

简介:A7105範例程式是一套面向无线通信初学者的A7105芯片开发示例包,包含发射端与接收端完整代码,覆盖芯片寄存器配置、SPI接口操作及无线数据收发流程,适合嵌入式爱好者、学生或工程师快速上手短距离ISM频段通信开发。压缩包共41…

2026/8/31 1:05:20

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/31 2:14:20

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/1 7:04:43

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/1 0:00:42

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/1 0:00:42

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/1 0:00:42

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

2026/9/1 0:00:42

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/1 0:00:42

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/1 0:00:42

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…