如何用SQL FIRST_VALUE获取首条记录?

风敏姑娘_1864

风敏姑娘_1864

2026-08-26

193人浏览

原创

first_value返回的不是物理首行,因为它只按order by定义的逻辑顺序取值,未指定order by则报错,排序字段重复或含null时结果不确定;必须用稳定排序(如order by created_at, id)并显式指定窗口帧才能确保一致性。

如何用sql first_value获取首条记录?

FIRST_VALUE 为什么返回的不是表里第一条?

因为 FIRST_VALUE 是窗口函数,它不看物理存储顺序,只看 ORDER BY 子句定义的逻辑顺序。没写 ORDER BY 就直接报错;写了但排序字段有重复值,结果就可能“飘”——比如按 status 排序,多个 'active' 行,数据库选哪个当“第一”是不确定的。

常见错误现象:FIRST_VALUE(name) OVER (PARTITION BY dept_id) 没加 ORDER BY → 直接报错;加了 ORDER BY created_at 但多个记录时间相同 → 每次执行结果可能不同。

  • 必须搭配 ORDER BY,哪怕只是 ORDER BY id 这种主键字段
  • 如果想稳定取“插入顺序第一条”,确保排序字段能唯一确定顺序(如自增 id 或带毫秒的 created_at
  • PARTITION BY 不加也行,此时整个结果集视为一个分区

怎么用 FIRST_VALUE 取每个分组的首条记录?

典型场景:查每个部门薪资最高的员工姓名(注意不是最高薪资,而是对应那条记录的姓名)。这时候不能只靠 MAX(salary),得把整行关联信息带出来。

实操建议:用 FIRST_VALUE 配合 PARTITION BY dept_id ORDER BY salary DESC,再用 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 确保窗口覆盖全分区(默认就是这个范围,可省略)。

Flova
Flova

Flova是一款AI文本写作工具,全球首个一体化 AI 视频创作平台。

下载
  • 排序方向很重要:ORDER BY salary DESC 才能拿到最高薪那条的 name,反过来就变成最低薪的
  • 别漏掉 PARTITION BY,否则所有部门混在一起只算一个“首条”
  • 如果要取多列(比如姓名+薪资),得对每列分别写 FIRST_VALUE,不能一次取整行
SELECT
  dept_id,
  name,
  salary,
  FIRST_VALUE(name) OVER (PARTITION BY dept_id ORDER BY salary DESC) AS top_name,
  FIRST_VALUE(salary) OVER (PARTITION BY dept_id ORDER BY salary DESC) AS top_salary
FROM employees;

FIRST_VALUE 和 LIMIT 1 / ROW_NUMBER() 有什么区别?

FIRST_VALUE 是“复制首条值到当前行”,不是过滤出首条记录。很多人误以为它能替代 ROW_NUMBER() = 1 的筛选逻辑,结果发现返回行数没变,只是多了一列重复值。

性能影响:在大数据集上,FIRST_VALUE 要为每一行计算窗口,而 ROW_NUMBER() + WHERE rnk = 1 可以配合索引快速定位,后者通常更快、更省内存。

  • 想“取出”首条记录 → 用 ROW_NUMBER() OVER (...) AS rnk + WHERE rnk = 1
  • 想“标记”当前行所属分组的首条值 → 才用 FIRST_VALUE
  • MySQL 8.0+、PostgreSQL、SQL Server 都支持;SQLite 支持但版本需 ≥ 3.25;旧版 MySQL 不支持窗口函数

容易被忽略的 NULL 处理和数据类型陷阱

FIRST_VALUE 默认跳过 NULL 值——如果排序字段是 NULL,那行会被排除在窗口排序外,可能导致你预期的“第一条”实际被跳过。另外,返回值类型严格继承源列,比如 FIRST_VALUE(price) 返回 DECIMAL,但若和 INT 字段做运算可能隐式转换失败。

  • 显式控制 NULL 排序位置:ORDER BY status NULLS LAST(PostgreSQL/Oracle)或 ORDER BY IFNULL(status, 'zzz')(MySQL)
  • 避免跨类型比较:不要拿 FIRST_VALUE(name) 直接跟数字字段 = 判断
  • 某些数据库(如早期 SQL Server)对 FIRST_VALUERESPECT NULLS / IGNORE NULLS 参数支持不一致,建议统一用 COALESCE 预处理源字段
窗口函数的边界和排序依赖比看起来更敏感,尤其是当业务要求“稳定可重现”时,光写对语法远远不够——排序字段是否唯一、NULL 怎么落、分区键有没有隐式类型转换,都得一个个对上。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3703

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

791

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

949

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5461

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2463

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5460

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7101

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

970

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

852

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.1万人学习