如何将MySQL窗口函数为?

摘要:一、核心基础 1.1 定义与核心特性 窗口函数(Window Function)又称开窗函数,是My
一、核心基础 1.1 定义与核心特性 窗口函数(Window Function)又称开窗函数,是MySQL 8.0版本新增的高级查询特性,核心作用是对数据集的指定窗口(即数据子集)进行精准计算。 ======= 🌟 青柠来相伴,代码更简单。🌟 ======= 📚 本文所有内容,我都整理在了 青柠合集 里。👇 🎯 搜索关注【青柠代码录】,即可查看所有合集文章 ~ ======= 🌟 ================ 🌟 ======= 区别于传统GROUP BY聚合函数,其最大优势是不压缩原表行数、不丢失明细数据——每一行数据都会生成对应的计算结果,实现“单行明细数据”与“窗口汇总数据”同屏展示,完美弥补传统GROUP BY聚合后,丢失明细的缺陷,这也是开发中优先使用窗口函数的核心原因。 窗口函数的三大核心特性: 明细保留:原表所有行完整留存,不会像GROUP BY那样,将分组数据合并为一行,而是在每行明细后,新增窗口计算结果列,实现“一行看尽个人数据与分组汇总数据”,适配报表开发中“明细+汇总”同表展示的需求。 分区独立:通过PARTITION BY子句划分数据分区,每个分区内的窗口计算相互隔离、互不干扰。例如按部门分区计算薪资排名,技术部的排名仅在技术部内部生效,不会与产品部、销售部的员工混淆,这是窗口函数实现“分组计算”的核心逻辑。 范围可控:支持通过帧边界子句(ROWS/RANGE),自定义窗口内参与计算的行范围,可实现累计计算、移动计算、区间计算等精细化需求,例如“近3天订单金额移动平均”“从分区首行到当前行的累计销售额”,适配复杂统计场景。 1.2 与GROUP BY深度对比 很多开发者在使用时,会混淆窗口函数与GROUP BY聚合函数,二者核心差异体现在数据处理方式、结果行数、计算范围等5个关键维度: 数据处理方式:GROUP BY聚合函数,会将相同分组的多行数据合并为一行,仅返回分组汇总结果,彻底丢失单行明细数据;窗口函数则不会合并行,分组后保留所有单行明细,同时在每行新增窗口计算结果,明细与汇总兼顾。 结果行数:GROUP BY的结果行数等于分组数量,例如3个部门分组,结果仅返回3行部门汇总数据;窗口函数的结果行数与原表完全一致,原表有9条员工数据,执行窗口函数后仍返回9条数据,仅新增计算列。 计算范围:GROUP BY仅能对整个分组做全局聚合,无法精细化控制计算的行范围,例如无法实现“分组内从当前行向前3行的平均薪资”;窗口函数可通过ROWS/RANGE子句自定义分区内的计算行范围,支持累计、移动、首尾行等多种精细化计算。 SQL执行顺序:GROUP BY的执行时机早于WHERE、HAVING之后,先筛选数据再分组聚合;窗口函数的执行时机晚于WHERE、GROUP BY、HAVING,早于ORDER BY、LIMIT,这也是“窗口函数不能直接写在WHERE子句中”的核心原因。 适用场景:GROUP BY适用于简单汇总统计、分组求和/计数,例如“统计每个部门的员工总数”“计算每个部门的薪资总额”;窗口函数适用于排名榜单、跨行对比、累计计算、分组TopN、复杂报表、同比环比等场景,例如“每个部门薪资排名”“员工薪资与部门平均薪资对比”“每日销售额累计求和”。 1.3 语法详解 MySQL窗口函数的标准语法遵循“函数+OVER子句”的结构,OVER子句是窗口函数的核心,所有分区、排序、范围控制,均通过OVER子句实现: -- 完整语法 窗口函数名([参数]) OVER ( PARTITION BY 分区字段1, 分区字段2... -- 分区子句:可选,划分数据窗口(核心) ORDER BY 排序字段1 [ASC/DESC], 排序字段2... -- 排序子句:可选,分区内排序(影响排名、累计结果) [ROWS | RANGE] BETWEEN 起始边界 AND 结束边界 -- 帧边界子句:可选,定义计算行范围 ) AS 计算结果别名 关键字逐句拆解(结合开发场景,说明使用注意事项): 窗口函数名:MySQL内置的窗口函数分为四大类(排名类、聚合类、跨行取值类、分布类),不同函数的参数要求不同,例如排名类函数无需参数,分位数函数需要指定分位值参数,后续会详细讲解。 OVER关键字:窗口函数的唯一标识,必须存在!如果省略OVER子句,该函数会变成普通聚合函数,这是区分窗口函数与普通聚合函数的关键。 PARTITION BY子句:分区关键字,核心作用是将整个数据集按指定字段拆分为多个独立的子窗口,每个子窗口内的计算相互独立。例如“PARTITION BY dept_name”表示按部门拆分窗口,技术部、产品部、销售部分别作为独立窗口计算。
阅读全文