SQL如何获取分组中第一条或最后一条记录_利用FIRST_VALUE函数
SQL如何获取分组中第一条或最后一条记录:利用FIRST_VALUE函数

为什么FIRST_VALUE返回的不是“每组第一条记录”?
很多朋友第一次用FIRST_VALUE窗口函数时,都会遇到一个困惑:结果怎么和想的不一样?它确实按你指定的顺序,取到了窗口里的第一个值,但问题是——它把那个值“复制”给了组里的每一行,行数一点没少。这就像给团队每个人都发了一份队长的名片,但队长本人并没有被单独请出来。而我们实际业务中想要的,往往是“每组只留一条代表记录”,比如最新的那笔订单、最早的那次登录、分数最高的那位学生。这时候你就会发现,FIRST_VALUE更像是个辅助工具,单靠它,解决不了“提取整行数据”这个核心问题。
怎么用FIRST_VALUE配合ROW_NUMBER拿到完整记录?
那么,正确的“组合拳”该怎么打呢?核心思路其实很清晰:分两步走。第一步,用ROW_NUMBER()给每个分组内的行,按照你的排序规则(比如时间倒序)编上号(1,2,3…)。第二步,在外层查询里,轻松地WHERE rn = 1,只把每组的“1号”选手筛选出来。在这个过程中,FIRST_VALUE可以作为一个验证字段出现,但它不是筛选的主力。
这里有三个关键点必须注意:
- 排序是灵魂:
ORDER BY子句必须明确写在OVER()里面,否则ROW_NUMBER的编号顺序就是不确定的,结果自然不可靠。 - 分组要对齐:
PARTITION BY里的字段(比如user_id),必须和你想分组的逻辑完全一致。 - “最后一条”怎么取:很简单,把
ORDER BY created_at DESC改成ASC就行了。当然,你也可以用LAST_VALUE,但要小心它的默认窗口范围,最好显式指定为RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,以免出错。
来看一个经典例子(获取每个用户的最新订单):
SELECT order_id, user_id, amount, created_at
FROM (
SELECT order_id, user_id, amount, created_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
FROM orders
) t
WHERE rn = 1;
FIRST_VALUE在SELECT里直接用有哪些陷阱?
如果把FIRST_VALUE当成“取一行”的函数来用,很容易踩坑。因为它本质上是个“填充”函数,不负责删减行数。下面这几种情况,就是典型的误用:
- 场景一:想找“每组金额最高的订单号”。如果直接写
FIRST_VALUE(order_id) OVER (PARTITION BY user_id ORDER BY amount DESC),结果会是每一行都显示同一个最高的订单号,但你却看不到这个订单对应的金额、时间等其他信息。这显然不是我们想要的完整记录。 - 场景二:忘了写
ORDER BY。这时数据库可能会按物理存储顺序来排,每次执行的结果都可能不同,毫无稳定性可言。 - 场景三:在聚合查询里混用。窗口函数和
GROUP BY聚合不能直接放在同一层SELECT中,否则要么报错,要么语义变得混乱不清。
所以,更稳妥的做法是:要么先用子查询或CTE把窗口计算的结果准备好,再去做关联查询;要么就坚持使用ROW_NUMBER配合过滤的方案,思路直观,控制力也强。
MySQL 8.0+ 和 PostgreSQL 的行为差异要点
虽然主流数据库都支持这些窗口函数,但魔鬼藏在细节里,跨平台使用时尤其要注意:
- MySQL 8.0+ 更“较真”:它对
ORDER BY子句里的表达式要求更严格。比如,你不能直接使用SELECT列表里定义的别名(像ORDER BY dt),必须写原始字段名或列位置。 - PostgreSQL 处理空值更灵活:它支持
ORDER BY ... NULLS FIRST/LAST语法,让你能明确控制空值排在前面还是后面,这在MySQL里目前还不行。 - SQL Server 有“捷径”:在某些简单场景下,使用
TOP 1 WITH TIES配合FETCH NEXT子句,写起来可能比窗口函数更简短。但这种方法不具备跨多个分组分别取第一条的能力,功能上还是有区别的。
总的来说,如果考虑代码的兼容性和可读性,ROW_NUMBER方案是更安全的选择。而FIRST_VALUE,更适合扮演一个“锦上添花”的角色,用来生成一些派生字段,不建议让它承担核心的数据筛选逻辑。
相关攻略
什么是Modbox? 想快速为你的项目找到一个打动人的核心卖点吗?Modbox就是为这个目标而生的。它是一款功能强大且完全免费的AI工具,专门服务于企业家和初创团队,核心任务就是帮大家挖掘并呈现独特的商业价值。 简单来说,Modbox能从市场营销的实际挑战出发,为你提供一揽子解决方案。无论是精准定位
SQL窗口函数实战:如何精准获取分组后的第一条记录 在数据库查询中,一个高频需求是:从每个分组里,精准地取出第一条记录。听起来简单,但实际操作时,版本兼容、排序语义、性能陷阱等问题接踵而至。今天,我们就来把这个需求彻底拆解清楚。 为什么FIRST_VALUE在MySQL 8 0之前根本用不了 核心原
SQL窗口函数:为什么你的LAST_VALUE()总取不到“最后”那个值? 先看一个典型的“翻车”现场: LAST_VALUE默认返回当前行值,因其窗口帧为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,仅覆盖当前行及之前行;要取分组末值,须显式指定
SQL如何获取分组中第一条或最后一条记录:利用FIRST_VALUE函数 为什么FIRST_VALUE返回的不是“每组第一条记录”? 很多朋友第一次用FIRST_VALUE窗口函数时,都会遇到一个困惑:结果怎么和想的不一样?它确实按你指定的顺序,取到了窗口里的第一个值,但问题是——它把那个值“复制”
Cookie确实在WEB应用方面为访问者和编程者都提供了方便,然而从安全方面考虑是有问题的 首先,Cookie数据会随着HTTP请求和响应的包头进行明文传输,这意味着在传输过程中,这些数据可能被第三方截获和查看。其次,Cookie通常以文本文件的形式存储在用户的浏览器缓存目录中,其中可能包含用户的会
热门专题
热门推荐
制作PPT用什么软件好?2024年五大主流工具深度评测 无论是职场汇报、学术答辩还是项目路演,一份专业且吸引人的PPT演示文稿都至关重要。面对众多制作工具,如何选择最适合自己的那一款?本文将对五款主流的PPT软件进行全方位对比分析,从功能、协作、设计到易用性,助您根据核心需求做出最佳决策,高效打造令
今日A股市场整体走势偏弱,朗玛信息(股票代码300288)股价同步调整,截至收盘下跌3 16%,全天成交额4783 73万元,换手率为1 77%,公司总市值约为35 21亿元。股价的短期波动,引发了投资者对其核心投资逻辑与未来潜在机会的深入探讨。 异动深度解析:AI医疗战略的机遇与挑战 朗玛信息是市
《超级蠕虫大战圣诞老人2》是一款休闲益智游戏,攻略涵盖基本操作、关卡解锁与道具使用。玩家需掌握战斗策略与技能升级,熟悉敌人特性和环境机制。合理运用道具并完成隐藏任务可获取奖励,多人模式注重策略博弈。建议多练习并参与社区交流,同时注意游戏时长以保护视力。
在Kimi里搜索“2026年北京积分落户政策细则”,如果跳出来的总是房产中介的软文、培训机构的广告或者各种自媒体猜测,那说明默认的联网检索没有经过过滤。想要获得干净、权威的结果,必须主动使用结构化的提示词进行限定。 用结构化提示词锁定权威信源 这一步是关键,直接决定了你看到的信息是来自官方发布渠道,
为避免代码丢失,Qoder编辑器需手动开启自动保存功能。全局设置中可开启开关并选择触发条件,如按时间间隔或窗口失去焦点时保存。还可为特定项目单独配置,覆盖全局设置。若功能失效,需检查文件位置是否只读、用户权限是否足够,并避免直接编辑受保护的系统文件。





