MySQL8 窗口函数是真的省事!
@[toc] MySQL9 已经出来了,MySQL8 相信也慢慢走进各位小伙伴的工作中了。
MySQL8 还是有很多重量级变化的,一些底层优化大家在使用中有时候不易察觉,但是有一些用法,还是带给我们耳目一新的感觉,今天松哥和大家分享一下 MySQL8 里边的窗口函数。
一 什么是窗口函数
在 MySQL 8 中,窗口函数(Window Functions)是一类强大的分析函数,允许你在查询结果集上执行计算,而无需将数据分组到多个输出行中。窗口函数通常与 OVER() 子句一起使用,以指定数据窗口,即窗口函数将要在其上执行计算的行集。
简单来说,窗口函数的作用类似于在查询中对数据进行分组,不同的是,分组操作会把分组的结果聚合成一条记录,而窗口函数是将结果置于每一条数据记录中。
窗口函数的格式类似下面这样:
<窗口函数> OVER ([PARTITION BY <分组列> [, <分组列>...]] [ORDER BY <排序列> [ASC | DESC] [, <排序列> [ASC | DESC]]...] [<rows or range clause>])
<窗口函数>
: 定义要在窗口中计算的聚合函数或其它分析函数,如COUNT
、RANK
、SUM
等。OVER
: 窗口函数的核心关键字。PARTITION BY
: 定义要用来分组的一组列名。ORDER BY
: 定义用来排序的一组列名。<rows or range clause>
: 定义窗口的行集合。默认为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
,表示窗口包括从窗口开始到当前行的所有行。
接下来我们通过一个实际案例来体会下窗口函数。
二 窗口函数实践
2.1 统计成绩和排名
假设我有如下一张表:
我现在想要计算学生的考试总成绩以及单科成绩排名,利用窗口函数就能快速搞定,如下:
SELECT name,subject,score, SUM(score) OVER(PARTITION by name) AS '总分', DENSE_RANK() OVER(PARTITION by subject ORDER BY score DESC) AS '学科排名' from student
和窗口函数相关的就两列:
- sum 求总分,over 中按照 name 进行分组,相当于就是计算每个人的总分。
- dense_rank 是排序,这个函数会考虑并列的情况,但是并列并不影响排序,因为是计算每个人单科排名,所以就按照学科分组之后按照 score 排序。
最终执行结果如下:
2.2 销售统计
假设我有如下一张表:
这是一个名为 sales 的表,其中包含 id(销售记录 ID)、product_id(产品 ID)、sale_date(销售日期)和 amount(销售额)等字段。
现在有如下几个需求,大家把这几个需求搞懂了,基本上窗口函数就会用了。
计算累计销售额
需求:按产品 ID 分组,计算每个产品的累计销售额。
SELECT id, product_id, sale_date, amount, SUM(amount) OVER (PARTITION BY product_id ORDER BY sale_date) AS '累计销售额' FROM sales;
SUM(amount) OVER (PARTITION BY product_id ORDER BY sale_date) AS '累计销售额'
表示按 product_id 分组,按 sale_date 排序,计算每个产品的累计销售额。
最终查询结果如下:
计算移动平均值
需求:按产品 ID 分组,计算每个产品的最近 3 笔销售记录的移动平均销售额。
SELECT id, product_id, sale_date, amount, AVG(amount) OVER (PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS '移动平均销售额' FROM sales;
AVG(amount) OVER (PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS '移动平均销售额'
表示按product_id
分组,按sale_date
排序,计算当前行及前两行的平均销售额。
最终查询结果如下:
计算排名
需求:按产品 ID 分组,计算每个销售记录在该产品中的排名。
SELECT id, product_id, sale_date, amount, RANK() OVER (PARTITION BY product_id ORDER BY amount DESC) AS '销售金额排名' FROM sales;
RANK() OVER (PARTITION BY product_id ORDER BY amount DESC) AS '销售金额排名'
表示按 product_id 分组,按 amount 降序排序,计算每个销售记录在该产品中的排名。
最终查询结果如下:
计算百分比排名
需求:按产品 ID 分组,计算每个销售记录在该产品中的百分比排名。
SELECT id, product_id, sale_date, amount, PERCENT_RANK() OVER (PARTITION BY product_id ORDER BY amount DESC) AS '百分比排名' FROM sales;
PERCENT_RANK() OVER (PARTITION BY product_id ORDER BY amount DESC) AS '百分比排名'
表示按 product_id 分组,按 amount 降序排序,计算每个销售记录在该产品中的百分比排名。
最终查询结果如下:
计算前后行的差值
需求:按产品 ID 分组,计算每个销售记录与上一个销售记录之间的销售额差值。
SELECT id, product_id, sale_date, amount, LAG(amount, 1) OVER (PARTITION BY product_id ORDER BY sale_date) AS '上个销售记录', amount - LAG(amount, 1) OVER (PARTITION BY product_id ORDER BY sale_date) AS '差额' FROM sales;
LAG(amount, 1) OVER (PARTITION BY product_id ORDER BY sale_date)
:按 product_id 分组,按 sale_date 排序,获取当前行的上一行的 amount 值。amount - LAG(amount, 1) OVER (PARTITION BY product_id ORDER BY sale_date)
:计算当前行与上一行的销售额差值。
最终查询结果如下:
计算第一个和最后一个值
需求:按产品 ID 分组,计算每个产品的第一个和最后一个销售日期。
SELECT product_id, MIN(sale_date) OVER (PARTITION BY product_id) AS '第一个销售日期', MAX(sale_date) OVER (PARTITION BY product_id) AS '最后一个销售日期' FROM sales;
MIN(sale_date) OVER (PARTITION BY product_id)
:按product_id分组,计算每个产品的第一个销售日期。MAX(sale_date) OVER (PARTITION BY product_id)
:按product_id分组,计算每个产品的最后一个销售日期。
最终查询结果如下:
好啦,通过这几个小小案例,小伙伴们明白窗口函数了吧~

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
微软开源基于 Rust 的 OpenHCL
微软宣布推出新的开源虚拟化堆栈 OpenHCL paravisor,以便使用这个由 Rust 编写的软件堆栈来支持 Intel TDX 和 AMD SEV-SNP 机密计算虚拟机 (VM)。据悉,微软的这项工作已经进行了五年,现如今正式开源。 OpenHCL 是一个执行环境,可作为机密计算虚拟机的辅助程序,由 AMD SEV-SNP 或 Intel TDX 提供硬件保护。OpenHCL 可以在 x86_64 和 ARM64 上运行,但目前仅支持 Intel 和 AMD 机密计算平台;ARM64 方面的计划是支持 Arm CCA(机密计算架构)。目前,OpenHCL 已经在 Azure 上使用。 OpenHCL 可为为机密和非机密 VM 提供: 通过标准设备接口进行设备仿真,本质上提供了一组仿真设备,例如 vTPM 和 serial。 通过标准设备接口进行设备转换,例如 NVMe 到para-virtualized SCSI,允许将硬件设备直接分配给 VM(加速 IO),而无需更改客户操作系统 ,从而使虚拟机能够充分利用尖端设备的性能。 诊断支持,特别适用于在难以使用传统调试方法的情况下...
- 下一篇
Typst 0.12 发布:全方位提升的排版系统
开源排版工具 Typst 推出了备受期待的 0.12 版本。本次更新不仅带来了多项重磅功能,涵盖布局、PDF 输出和性能优化,还对软件的底层架构进行了深入改进。Typst 0.12 版本的发布标志着该排版工具的进一步成熟,也让开发者和文档创作者们能够以更高效的方式处理复杂的排版任务。 持续创新的 Typst 自 2019 年推出以来,Typst 一直致力于打造一个从最简单到最复杂文档都能胜任的排版引擎。Typst 不仅继承了 LaTeX 等排版系统的优点,还融入了许多全新的设计理念,为用户提供了更直观且灵活的操作方式。本次发布的 Typst 0.12 版本是历时六个月的开发成果,它大幅优化了布局和排版性能,同时对 PDF 输出格式进行了改进,展示了 Typst 不断进步的实力。 Typst 0.12 的更新并不只局限于表面功能的提升。开发团队进行了大量底层重构,为未来的功能扩展和改进奠定了坚实的基础。值得注意的是,Typst 未来计划支持 HTML 输出、更加易访问的 PDF 以及更强大的布局能力,Typst 0.12 已经为这些功能打下了必要的基础。 强大的新布局功能 在 Typst...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库