新特性解读 | MySQL 8.0 窗口函数一次疑问解答

数据库- 公用表表达式-窗口函数 公用表表达式 有案例 阅读详情

作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


记起来有一次去讲 MySQL 8.0 开发相关特性,在 QA 环节,有人对 MySQL 的几个非常用窗口函数有些困惑,当时现场给了一些示范并且做了详细的解答,今天我用几个简单例子分享下具体的用法。

有困惑的是这四个窗口函数(其实是因为我PPT里仅写了这四个窗口函数):frist_value、last_value、nth_value、ntile 。

谈到这四个窗口函数的具体用法,特别是前两个,得先熟悉 MySQL 窗口函数的框架用法。这里提到的窗口函数框架,其实就是定义一个分组窗口的边界,边界可以是具体的行号,也可以是具体的行内容,以这个边界为起点或者终点,来展现分组内的过滤数据。详情见我之前的发稿:https://opensource.actionsky.com/20210125-mysql/

接下来我们来看看这四个窗口函数如何使用。

  1. first_value: 用来返回一个分组窗口里的第一行记录,也即排名第一的那行记录。

我们用表t1来示范,这张表里只有12行记录,其中每6行记录按照字段r1来分组。

   localhost:ytt_new>select id,r1,r2 from t1;
   +----+------+------+
   | id | r1   | r2   |
   +----+------+------+
   |  1 |   10 |   20 |
   |  2 |   10 |   30 |
   |  3 |   10 |   40 |
   |  4 |   10 |   50 |
   |  5 |   10 |    2 |
   |  6 |   10 |    3 |
   |  7 |   11 |  100 |
   |  8 |   11 |  101 |
   |  9 |   11 |    1 |
   | 10 |   11 |    3 |
   | 11 |   11 |   10 |
   | 12 |   11 |   20 |
   +----+------+------+
   12 rows in set (0.00 sec)

比如想拿到每个分组里的第一名(升序),可以用row_number()函数,我们来回顾下:

   localhost:ytt_new>select r1,r2 from (select r1,r2,row_number() over(partition by r1 order by r2) as rn from t1) T where T.rn = 1;
   +------+------+
   | r1   | r2   |
   +------+------+
   |   10 |    2 |
   |   11 |    1 |
   +------+------+
   2 rows in set (0.00 sec)

此时如果用first_value来实现,写法会更加简单:

      localhost:ytt_new>select distinct r1,first_value(r2) over(partition by r1 order by r2) as first_r2 from t1;
      +------+----------+
      | r1   | first_r2 |
      +------+----------+
      |   10 |        2 |
      |   11 |        1 |
      +------+----------+
      2 rows in set (0.00 sec)
  1. last_value: 和first_value相反,用来返回分组窗口里的最后一行记录,也即倒数第一的那行记录。

比如我取出对应分组内最后一行 r2 的值,如果用 last_value 函数,非常好实现,可结果和预期不一致:返回与字段 r2 本身等值的记录。

   localhost:ytt_new>select distinct r1,last_value(r2) over(partition by r1 order by r2) 'last_r2' from  t1; +------+---------+
   | r1   | last_r2 |
   +------+---------+
   |   10 |       2 |
   |   10 |       3 |
   |   10 |      20 |
   |   10 |      30 |
   |   10 |      40 |
   |   10 |      50 |
   |   11 |       1 |
   |   11 |       3 |
   |   11 |      10 |
   |   11 |      20 |
   |   11 |     100 |
   |   11 |     101 |
   +------+---------+
   12 rows in set (0.01 sec)

究其原因是函数last_value的默认框架是 rows between unbounded preceding and current row 。这里默认框架意思是:限制窗口函数的取值边界为当前行和上限无穷大,所以对应的值就是当前行自己。

那正确的框架应该是什么样呢?正确的框架应该是让边界锁定整个分组的上下边缘,也即整个分组的上限与下限之间。所以正确的写法如下:

   localhost:ytt_new>select distinct r1,last_value(r2) over(partition by r1 order by r2 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as 'last_r2' from t1;
   +------+---------+
   | r1   | last_r2 |
   +------+---------+
   |   10 |      50 |
   |   11 |     101 |
   +------+---------+
   2 rows in set (0.00 sec)
  1. nth_value: 用来返回分组内指定行的记录。

比如用nth_value函数来求分组内排名第一的记录:

   localhost:ytt_new>select * from (select distinct r1,nth_value(r2,1) over(partition by r1 order by r2) 'first_r2' from  t1) T where T.first_r2 is not null;
   +------+----------+
   | r1   | first_r2 |
   +------+----------+
   |   10 |        2 |
   |   11 |        1 |
   +------+----------+
   2 rows in set (0.00 sec)

这个函数的功能基本和函数row_number一致。不同的是row_number用来展示排名,而nth_value用来输入排名。

  1. ntile: 用来在分组内继续二次分组。

比如我想取出分组内排名前50%的记录,可以这样写:

   localhost:ytt_new>select id,r1,r2 from (select id,r1,r2, ntile(2) over(partition by r1 order by r2) 'ntile
   ' from t1) T where T.ntile=1;
   +----+------+------+
   | id | r1   | r2   |
   +----+------+------+
   |  5 |   10 |    2 |
   |  6 |   10 |    3 |
   |  1 |   10 |   20 |
   |  9 |   11 |    1 |
   | 10 |   11 |    3 |
   | 11 |   11 |   10 |
   +----+------+------+
   6 rows in set (0.00 sec)

这四个窗口函数,特别是 last_value 需要注意。 不过在大多数场景下,记住几个常用的窗口函数即可,比如 row_number(),rank() 等等。

Java后端面试核心问题解析:HashMap、Spring事务、JVM与SQL优化 在Java后端开发中,数据结构与并发控制是基础但关键的技术点。HashMap作为核心数据结构,其线程安全问题直接影响系统稳定性,典型表现为多线程环境下的数据覆盖与死循环问题。Spring事务管理基于AOP实现,涉及传播机制与隔离级别等核心概念,配置不当会导致事务失效等严重问题。JVM内存管理与GC调优直接影响应用性能,Full GC问题需要结合堆内存分析与工具定位。SQL优化则涉及索引设计与执行计划解读,是数据库性能的关键。这些技术共同构成了Java后端工程师的核心能力矩阵,在电商、金融等高并发场景尤为重要 阅读详情

相关推荐

技术博客如何构建高可信度:从.NET实践看内容、验证与信任基建

技术博客的本质不是知识搬运,而是工程化信任的持续交付。在.NET等企业级技术生态中,开发者亟需的不再是API用法罗列,而是可验证的原理推演、真实场景下的权衡决策、以及经得起生产环境考验的代码方案。本文聚焦‘可信技术内容’这一核心概念,解析其背后的技术原理(如性能数据闭环验证、跨层溯源分析)、工程价值(降低线上故障率、缩短问题定位时间)、典型应用场景(高并发库存扣减、AOT冷启动优化、GC调优),并以国内标杆博客‘老赵点滴’为案例,展现如何通过自研工具链、全链路测试体系与读者共建机制,将一篇博客升维为可复用、

337

[Mysql] FIRST_VALUE()函数 | LAST_VALUE()函数 | NTH_VALUE()函数

FIRST_VALUE()函数 | LAST_VALUE()函数 | NTH_VALUE()函数

Hudas的博客 6448

JMeter接口性能测试实战:从脚本编写到瓶颈定位

接口性能测试是保障软件系统稳定性和可扩展性的关键环节,其核心在于模拟真实用户负载,评估系统在高并发下的表现。其原理是通过工具模拟多用户并发请求,收集响应时间、吞吐量等关键指标,从而发现系统瓶颈。掌握性能测试技术,对于构建高可用、高性能的应用架构具有重要价值,广泛应用于电商、金融、社交等对实时性要求高的场景。本文聚焦于业界广泛使用的开源工具JMeter,深入探讨如何构建完整的接口压测体系。文中将详细解析如何通过参数化、关联等高级技巧处理动态数据,并针对常见的“jmeter调取登录token网页400”等实战问

weixin_33829657的博客 388

MySQL数据库基础:各类窗口函数操作一文详解

窗口函数适用场景:对分组统计结果中的每一条记录进行计算的场景下, 使用窗口函数更好。窗口函数(Window Function)可以像聚合函数一样对一组数据进行分析并返回结果,二者的不同之处在于,窗口函数不是将一组数据汇总成单个结果,而是为每一行数据都返回一个结果。聚合函数和窗口函数的区别如下图所示。窗口函数可以分为静态窗口函数和动态窗口函数,其中,静态窗口函数的窗口大小是固定的,不会因为记录的不同而不同;动态窗口函数的窗口大小会随着记录的不同而变化。

master_hunter的博客 3847

Oracle 高级查询之分析函数部分--first_value,last_value

Oracle 高级查询之分析函数部分--first_value,last_value

1、Ovirt 开源虚拟化平台安装

Ovirt虚拟化Node和Engine安装

大鱼 6266

firstvalue函数mysql_MySQL 窗口函数之头尾函数

本文标识:MQ0018本文编辑 :长安月下赏美人儿编程工具 :MySQL、DBeaver阅读时长 :6分钟1、头尾函数(1)应用场景:快速查看某个窗口范围中的第一个或者最后一个指定的字段的数值(2)头尾函数分类及基础语法FIRST_value(指定字段)OVER(PARTITION BY 分区的字段 ORDER BY 排序的字段 DESC/ASC)LAST_value(字段)OVER (PART...

weixin_42717586的博客 1860

用STM32定时器PWM高级功能驱动步进电机:F103C8T6+TB6600实战教程

本文详细介绍了如何利用STM32F103C8T6微控制器的定时器PWM高级功能驱动TB6600步进电机驱动器,实现高效、灵活的运动控制方案。通过硬件配置、PWM参数计算、运动控制算法及TB6600高级功能应用的全面解析,为工业自动化和精密控制领域提供了实用的技术参考。

game4的博客 185

最全MySQL8.0实战教程 12 MySQL的函数 12.7 窗口函数【8 头尾函数 - FIRST_VALUE和LAST_VALUE】

最全MySQL8.0实战教程 12 MySQL的函数 12.7 窗口函数【8 头尾函数 - FIRST_VALUE和LAST_VALUE】

代码改变世界 635

《联邦学习实战》杨强 读书笔记十四——构建公平的大数据交易市场

当数据具有资产属性之后,数据便可以直接或者间接地为公司、为社会创造价值和收益,并且可以作为一种特殊的商品在市场中进行交易。 与传统的商品交易相比,数据资产交易的市场前景更广阔,但同时也面临着很多的挑战,主要包括: 数据的质量、价格如何定义 在合法合规的前提下,数据的交易如何确保不会泄露用户的隐私 如何构建合理的激励机制来鼓励更多的参与方加入数据交易市场中 大数据交易 数据交易的定义 数据交易是指一种对数据进行买卖的行为,大数据交易由三方共同参与,分别为数据提供方、大数据交易平台和数据需求方:

IEEE802_11的博客 3431

【HSPiP应用指南】从理论到实践:如何利用汉森溶解度参数优化配方设计

本文深入解析了汉森溶解度参数(HSP)理论及其在配方设计中的核心价值,并详细介绍了如何利用HSPiP软件工具从理论走向实践。文章通过匹配溶解度参数、计算汉森距离(Ra),系统阐述了如何解决溶剂选择、颜料分散稳定性及扩散行为预测等关键问题,并结合界面气相色谱(IGC)等实验方法提升预测精度,旨在帮助配方师实现配方设计的可视化、可量化与高效优化。

weixin_29305313的博客 1643

2021Java开发面试解答:mysql查询表结构语句

第一阶段:架构师筑基必备技能 我觉得,但凡是个成年人应该都清楚扎实的基本功对自己的工作帮助有多重要。从各大招聘网站的招聘要求来看,第一条都明确说明需要扎实的Java基础。因此,一般笔试以及面试的第一轮,对基础的考察是比较多的。 其实我发现有很多开发几年了,基础知识都不扎实,比如说,简单地介绍一下Java8有哪些新特性吗,或者你比较擅长的新特性有哪些?要么回答的不完整,要么就是回答的牛头不对马嘴。 配套学习文档 大厂必问并发编程: JVM深入拆解: 网络编程与高效IO: MySQL进阶: 面试必问数据

m0_57983312的博客 93

ENVI5.6+SARscape实战:基于哨兵一号的PS与SBAS时序InSAR地表形变监测全流程解析

本文详细解析了使用ENVI5.6和SARscape软件基于哨兵一号数据进行PS与SBAS时序InSAR地表形变监测的全流程。从数据获取、预处理到PS-InSAR和SBAS-InSAR处理,提供了实用技巧和优化建议,帮助用户高效完成地表形变监测任务。

weixin_29245767的博客 1151

2026年Java面试趋势与核心考点解析

Java作为企业级开发的主流语言,其技术栈的演进始终围绕性能优化与分布式架构展开。从JVM内存模型到并发编程,核心原理的深入理解是工程师必备基础。随着云原生和AI技术的普及,ZGC垃圾回收器、GraalVM Native Image等新技术成为面试热点。在分布式领域,Seata事务框架与Kubernetes集成方案体现了微服务架构的最新实践。对于Java开发者而言,掌握Spring Boot 4.0的响应式编程特性和JDK21虚拟线程,能够有效应对高并发场景。本文基于2026年大厂真实面试数据,梳理了从JV

weixin_34414650的博客 292

CATIA二次开发——遍历几何图形集下的轴系及控制轴系生成位置

CATIA二次开发——轴系相关问题1.遍历几何图形集下的轴系2.解决轴系生成位置的问题 1.遍历几何图形集下的轴系 近期遇到的问题:遍历轴系的时候发现,AxisSystem属性的轴系只有放在轴系集合下,才能被找到,放在几何图形集或其他位置均不能被找到。本来想遍历几何图形集下的轴系元素,但是发现没有对应的属性,只能查找 几何图形集、几何元素、草图等元素,无法直接遍历轴系。 解决办法:(加入选择集,在选择集中筛选轴系类型) HybridBody axisHB = activePart.HybridBodies

WorkMan的博客 2729

直捣黄龙~

这篇文章描述了一个矩阵寻路问题,要求计算从起点到终点的最短路径数量及长度。主要思路是通过BFS算法解决:首先标记哨兵警戒区域为禁区,然后从起点出发进行广度优先搜索,记录每个位置的最短步数和路径条数。当到达终点时,输出路径数和步数;若不可达则返回(0,0)。算法使用队列实现BFS,同时处理路径统计和步数记录,适用于网格寻路类问题。

面试高手的博客 215

手撕SQL调优高频面试题(附真实踩坑案例)

SQL调优没有银弹!需要结合业务场景具体分析。记住这个调优优先级:索引优化 > 查询改写 > 参数调整 > 架构升级 > 换存储引擎(别一上来就分库分表,小心被面试官怼!

xiaoqian9997的博客 1718

Data+AI━━数仓建模的智能进化之路!

Data+AI━━数仓建模的智能进化之路!

ith321的博客 1744

秒懂Flink:Flink面试高频110题及答案解析终极指南

Apache Flink作为业界领先的流处理框架,在大数据面试中占据着重要地位。想要进入大厂从事大数据开发工作,掌握Flink的核心概念和面试技巧至关重要。本篇文章将为你解析Flink面试中最常见的110个高频问题,帮助你快速掌握Flink的核心知识点,轻松应对面试挑战!🚀 ## 📊 Flink面试知识点全景图 在深入具体问题之前,让我们先了解一下Flink面试的知识体系结构。Flink面

gitblog_01162的博客 708

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java面试核心知识点与JVM原理深度解析

Java作为主流编程语言,其核心知识点和JVM原理是开发者必须掌握的基础。从基础语法特性到面向对象设计,再到集合框架和并发编程,Java提供了丰富的技术栈支持复杂系统开发。JVM内存模型和GC算法直接影响应用性能,理解堆栈内存分配和分代收集原理对性能调优至关重要。在面试场景中,这些知识点常通过HashMap实现、多态机制等实际问题考察。掌握synchronized锁升级、volatile可见性等并发特性,能帮助开发者构建高性能线程安全应用。合理运用接口与抽象类、异常处理艺术等编码规范,可显著提升代码质量和可

weixin_33922672的博客 309

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

mysql first_value()_MySQL 常用操作

1 创建/打开/删除数据库create database db;create database db character set utf8mb4;use db;drop database db;alter database db character set utf8mb4;2 修复表mysqlcheck --all-databasesmysqlcheck --all-databases --fas...

weixin_32283253的博客 1073

mysql first value_开窗函数 First_Value 和 Last_Value

在Sql server 2012里面,开窗函数丰富了许多,其中带出了2个新的函数 First_Value 和 Last Value .现在来介绍一下这2个函数的应用场景.首先分析一下First_Value(),用法是根据Partition By对数据进行分区,如果忽略Partition By ,那么默认整块数据一个区域,然后根据Order By 进行排序,取出第一个值。;WITH CTE AS(S...

weixin_42306480的博客 1395

MySQL函数:`FIRST_VALUE()`与`LAST_VALUE()`获取分组内的第一个和最后一个值。

要正确获取每个部门最后入职的员工姓名,需要显式指定。

weixin_41455464的博客 1014

【MySQL数据库】MySQL聚合函数、时间函数、日期函数、窗口函数等函数的使用

MySQL数据库中提供了很丰富的函数,比如我们常用的聚合函数,日期及字符串处理函数等。SELECT语句及其条件表达式都可以使用这些函数,函数可以帮助用户更加方便的处理表中的数据,使MySQL数据库的功能更加强大。本篇文章主要为大家介绍几类常用函数的用法。本期我们将介绍MySQL函数,帮助你更好使用MySQL。

2201_75381449的博客 1267

mysql如何实现first_value_分析函数——FIRST_VALUE()和LAST_VALUE()

FIRST_VALUE()和LAST_VALUE()字面意思已经很直观了,取首尾记录值。例:查询部门最早发生销售记录日期和最近发生的销售记录日期SQL> select *from criss_sales order by dept_id,sale_date;DEPT_ID SALE_DATE GOODS_TYPE SALE_CNT------- ----------- ------...

weixin_39632467的博客 1933
上一篇: 技术分享 | 聊聊 MySQL 关机的故事
下一篇: 技术分享 | MySQL 字符集再探
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值