MySQL 窗口函数深度解析:语法、应用场景与性能优化

一、窗口函数核心概念

​本质​​:对一组与当前行相关联的行执行计算,​​不改变原表行数​
​与聚合函数的区别​​:

SELECT department, AVG(salary)  -- 普通聚合:每个部门一行
FROM employees
GROUP BY department;SELECT name, salary, AVG(salary) OVER(PARTITION BY department)  -- 窗口函数:保留所有行
FROM employees;
二、窗口函数完整语法结构
函数名([参数]) OVER ([PARTITION BY 分组字段][ORDER BY 排序字段 [ASC|DESC]][frame_clause]
)
1. 核心子句详解
  • ​PARTITION BY​​:横向切分窗口,类似 GROUP BY 但不聚合
  • ​ORDER BY​​:定义窗口内排序,影响排名类函数和累计计算
  • ​frame_clause​​:指定窗口范围,语法:
  • ROWS | RANGE BETWEEN frame_start AND frame_end
    2. 窗口帧类型(frame_clause)
  • 类型示例说明
    默认帧RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW默认与排序字段相关
    物理行偏移ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING包含前2行到后1行
    逻辑值范围RANGE BETWEEN INTERVAL 7 DAY PRECEDING AND CURRENT ROW时间范围窗口
三、常用窗口函数分类
1. 排序函数
SELECT product_id,sales,ROW_NUMBER() OVER(ORDER BY sales DESC) AS rank1,  -- 唯一连续序号RANK() OVER(ORDER BY sales DESC) AS rank2,        -- 允许并列跳号DENSE_RANK() OVER(ORDER BY sales DESC) AS rank3   -- 允许并列不跳号
FROM sales_data;
2. 聚合窗口函数
SELECT date,revenue,SUM(revenue) OVER(ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS 3d_avg,AVG(revenue) OVER(PARTITION BY YEAR(date)) AS year_avg
FROM daily_sales;
3. 分布分析函数
SELECT student_id,score,PERCENT_RANK() OVER(ORDER BY score) AS percentile,  -- 相对百分比排名CUME_DIST() OVER(ORDER BY score) AS cumulative_dist -- 累计分布
FROM exam_results;
4. 偏移函数
SELECT date,temperature,LAG(temperature, 1) OVER(ORDER BY date) AS prev_day_temp,  -- 前一行LEAD(temperature, 1) OVER(ORDER BY date) AS next_day_temp, -- 后一行FIRST_VALUE(temperature) OVER(PARTITION BY WEEK(date)) AS week_first_temp
FROM weather;
四、典型应用场景
1. 动态分组TopN
-- 获取每个部门薪资前三名
WITH ranked AS (SELECT name, department, salary,DENSE_RANK() OVER(PARTITION BY department ORDER BY salary DESC) AS rkFROM employees
)
SELECT * FROM ranked WHERE rk <= 3;
2. 累计计算
-- 计算累计销售额与移动平均
SELECT order_date,daily_sales,SUM(daily_sales) OVER(ORDER BY order_date) AS cum_sum,AVG(daily_sales) OVER(ORDER BY order_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS 7d_ma
FROM orders;
3. 数据差异分析
-- 对比每月销售额与上月差异
SELECT month,revenue,LAG(revenue, 1) OVER(ORDER BY month) AS prev_month,revenue - LAG(revenue, 1) OVER(ORDER BY month) AS mom_diff
FROM monthly_sales;
五、性能优化策略
1. 索引设计
-- 为窗口函数涉及的字段建立组合索引
ALTER TABLE sales ADD INDEX idx_dept_time (department, order_date);-- 执行计划检查
EXPLAIN 
SELECT product_id,SUM(quantity) OVER(PARTITION BY product_id ORDER BY sale_date)
FROM sales;
2. 分区剪枝优化
-- 结合WHERE条件减少处理分区
SELECT *
FROM (SELECT user_id,ROW_NUMBER() OVER(PARTITION BY city ORDER BY reg_date) AS rnFROM usersWHERE city IN ('北京','上海')  -- 提前过滤
) t
WHERE rn <= 100;
3. 避免重复计算
-- 使用WINDOW子句复用定义
SELECT AVG(sales) OVER w AS avg_sales,MAX(sales) OVER w AS max_sales
FROM sales_data
WINDOW w AS (PARTITION BY region ORDER BY month);
六、与临时表结合的高级用法
1. 分阶段计算
-- 第一阶段:计算基础窗口
CREATE TEMPORARY TABLE stage1 AS
SELECT user_id,SUM(amount) OVER(PARTITION BY user_id) AS total_amt
FROM transactions;-- 第二阶段:二次聚合
SELECT AVG(total_amt) AS avg_amt_per_user
FROM stage1;
2. 递归窗口计算
-- 计算员工管理链层级
WITH RECURSIVE emp_tree AS (SELECT emp_id, manager_id, 1 AS level,CAST(emp_id AS CHAR(100)) AS pathFROM employeesWHERE manager_id IS NULLUNION ALLSELECT e.emp_id,e.manager_id,et.level + 1,CONCAT(et.path, '->', e.emp_id)FROM employees eJOIN emp_tree et ON e.manager_id = et.emp_id
)
SELECT emp_id,level,path,RANK() OVER(ORDER BY level) AS hierarchy_rank
FROM emp_tree;
七、常见错误排查
​错误现象​​原因分析​​解决方案​
结果排序不符合预期未正确使用ORDER BY明确指定排序字段和方向
窗口范围计算错误ROWS与RANGE混淆使用确认需要物理行偏移还是逻辑值范围
性能急剧下降未加分区条件导致全表扫描添加WHERE条件或分区过滤
出现重复排名使用了ROW_NUMBER而非RANK根据业务需求选择正确的排名函数

八、版本特性差异
​MySQL版本​​窗口函数支持​
5.x❌ 不支持
8.0.2+✔️ 基础窗口函数
8.0.28+✔️ 新增NTH_VALUE()NTILE()等扩展函数

结语:最佳实践原则
  1. ​明确窗口范围​​:始终指定ROWS/RANGE避免意外结果
  2. ​慎用无界窗口​​:UNBOUNDED PRECEDING可能导致性能问题
  3. ​结合索引优化​​:为PARTITION BYORDER BY字段建立索引
  4. ​分阶段处理​​:对复杂计算使用临时表拆分步骤
  5. ​版本验证​​:生产环境确认MySQL版本支持情况
    -- 查看窗口函数执行计划
    EXPLAIN FORMAT=JSON
    SELECT ... [包含窗口函数的查询];-- 性能模式监控
    SELECT * FROM performance_schema.events_stages_history_long
    WHERE EVENT_NAME LIKE '%window%';

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新版Chrome浏览器加载eDrawings 3D Viewer控件网页查看DWG、DXF

eDrawings是一款由达索系统&#xff08;DASSAULT SYSTMES&#xff09;开发的免费跨平台CAD看图工具&#xff0c;专注于3D模型和2D工程图的查看、协作与共享。其核心功能包括多格式支持、动态模型展示、跨平台适配及轻量化操作体验&#xff0c;适用于工程设计、教育培训等领域。…

阿姆斯特朗数

阿姆斯特朗数也就是俗称的水仙花数&#xff0c;是指一个n位数&#xff0c;其各位数字的n次方之和等于该数本身。例如&#xff0c;153是一个水仙花数&#xff0c;因为153&#xff1d;13&#xff0b;53&#xff0b;33。请问100-10000所有水仙花数有哪些。 采用穷举法对范围之间的…

vmvare 虚拟机内存不足

centos 扩展物理卷df -hT / sudo du -hx --max-depth1 / | sort -rh | head -n 20 // 查看前20个的大文件 # 清理旧日志&#xff08;保留最近7天&#xff09; sudo find /var/log -type f -mtime 7 -delete sudo journalctl --vacuum-time7d # 清理yum缓存 sudo yum clean …

C++?继承!!!

一、引言 代码的复用对于代码的质量以及程序员的代码设计上都是非常重要的&#xff0c;C中的许多特性都体现了这一点&#xff0c;从函数复用、模板的引入到今天我们将一起学习的&#xff1a;继承 二、什么是继承&#xff1f; 1、继承的概念 继承(inheritance)机制是面向对象程…

Android设置界面层级为最上层实现

Android设置界面层级为最上层实现 文章目录 Android设置界面层级为最上层实现一、前言二、Android设置界面层级为最上层实现1、主要代码2、后遗症 三、其他1、Android设置界面层级为最上层小结2、悬浮框的主要代码悬浮框 注意事项&#xff08;1&#xff09;权限限制&#xff08…

Linux 了解篇

一、GNU 项目与 GPL 许可 &#xff08;一&#xff09;GNU 项目 GNU &#xff1a;GNU 是一个递归缩写&#xff0c;代表 "GNUs Not Unix"。GNU 项目旨在开发一个完全自由的操作系统&#xff0c;该操作系统基于 Unix 的设计理念但不包含 Unix 的代码。GNU 项目提供了大…

word 如何让公式居中,公式编号右对齐

问题&#xff1a; 如何让输入的公式居中&#xff0c;公式编号右对齐&#xff1f; 解决方法&#xff1a; 方法一&#xff1a;使用制表符 1、输入内容&#xff1a;先按一次“Tab”键&#xff08;制表符&#xff09;&#xff0c;然后键入公式&#xff0c;然后再按一次“Tab”键…

华为OD机试真题——最小循环子数组 (2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

OpenCv高阶(十七)——dlib库安装、dlib人脸检测

文章目录 前言一、dlib库简介二、dlib库安装1、本地安装&#xff08;离线&#xff09;2、线上安装 三、dlib人脸检测原理1、HOG 特征提取2、 SVM 分类器训练3、 滑动窗口搜索4、非极大值抑制&#xff08;NMS&#xff09; 四、dlib人脸检测代码1、导入OpenCV计算机视觉库和dlib机…

AD-PCB--AD20软件安装及中英文切换 DAY 2

1.软件安装 1.1 软件包下载 给你一个捷径&#xff1a; 1.2 安装过程&#xff08;安装过的人跳过就好&#xff0c;一般很多都支持懒人安装&#xff09; 双击其中的exe文件 点击下一步 选择中文 接受用户协议 下面这个弹窗有的没有。 建议勾选导入导出 安装目录&#xff0c…

单向循环链表与双向链表

单向循环链表的原理与应用 思考&#xff1a;对于单向链表而言&#xff0c;想要遍历链表&#xff0c;则必须从链表的首结点开始进行遍历&#xff0c;请问有没有更简单的方案实现链表中的数据的增删改查&#xff1f; 回答&#xff1a;是有的&#xff0c;可以使用单向循环的链表进…

Windows鼠标掉帧测试与修复

前言 这两天突然发现鼠标似乎有掉帧&#xff0c;但是掉的又不太明显&#xff0c;用着感觉似乎快速移动的时候会有一瞬间卡一下&#xff0c;但是眼睛又看不清楚&#xff0c;不太确定是不是自己的心理作用&#xff0c;非常难受。 如何判断鼠标是否掉帧 根据我的经验&#xff0…

U 盘数据恢复全攻略

目录 &#x1f4be; U盘数据误删怎么办&#xff1f;两款实用工具助你找回丢失文件&#xff01;1️⃣ Recover My Files&#xff1a;数据恢复的得力助手&#x1f4cc; 主要特点&#x1f6e0; 使用步骤详解1. 下载与安装2. 启动软件并选择恢复类型3. 选择U盘所在分区4. 选择文件恢…

HarmonyOS NEXT~鸿蒙系统运维:全面解析与最佳实践

HarmonyOS NEXT&#xff5e;鸿蒙系统运维&#xff1a;全面解析与最佳实践 摘要 本文深入探讨鸿蒙(HarmonyOS)系统的运维管理&#xff0c;从架构特点到日常维护操作&#xff0c;全面分析这一全场景分布式操作系统的运维要点。文章将介绍鸿蒙系统特有的分布式能力运维管理、性能…

基于 STM32 的智慧农业温室控制系统设计与实现

摘要 本文提出一种基于 STM32 微控制器的智慧农业温室控制系统设计方案,通过集成多类型环境传感器、执行机构及无线通信模块,实现对温室内温湿度、光照、土壤湿度等参数的实时监测与自动调控。文中详细阐述硬件选型、电路连接及软件实现流程,并附关键代码示例,为智慧农业领…

Appium+python自动化(五)- 模拟器

简介 Appium是做安卓自动化的一个比较流行的工具&#xff0c;对于想要学习该工具但是又局限于没 android 手机来说&#xff0c;可以通过安卓模拟器来解决该问题&#xff0c;下面就讲解使用appium连接安卓模拟器的操作步骤。而是由于手机数据线问题&#xff0c;也只好先用模拟器…

汽车充电桩专用ASCP210系列电气防火限流式保护器

1.概述汽车充电桩专用电气防火限流式保护器 电气防火限流式保护器可有效克服传统断路器、空气开关和监控设备存在的短路电流大、切断短路电流时间长、短路时产生的电弧火花大&#xff0c;以及使用寿命短等弊端&#xff0c;发生短路故障时&#xff0c;能以微秒级速度快速限制短…

Linux中磁盘分区与挂载

一、磁盘划分 1.1 了解磁盘 硬盘的接口类型 接口类型发展方向应用场景IDESATA I/II/III个人PC机SCSISAS服务器上 磁盘命名规则 OSIDE(并口)SATA(串口)SCSIRHEL5/dev/hda/dev/sda/dev/sdaRHEL6/dev/sda/dev/sda/dev/sdaRHEL7/dev/sda/dev/sda/dev/sda 1.2 磁盘划分 磁盘划…

【数据分析】什么是特征蒸馏?

引言 —— “ 在数据洪流中提炼真金——解密特征蒸馏的艺术。” 在数据爆炸的时代&#xff0c;我们每天产生的信息量已远超人类处理能力的极限。当企业拥有百万维的用户行为数据&#xff0c;医疗研究者面对TB级的基因测序记录&#xff0c;工程师试图从千万张图像中识别关键模式…

机器学习笔记【Week4】

一、 为什么要用神经网络&#xff1f; 逻辑回归只能处理线性可分问题。例如&#xff0c;经典的 XOR 异或问题无法用单层逻辑回归准确分类。神经网络通过多层结构和非线性激活函数&#xff0c;能学习复杂的决策边界&#xff0c;解决非线性问题。 二、神经网络的基本组成 神经网…