MAX/MIN仅返回单列极值且忽略NULL,无法直接获取对应整行数据;查极值所在行需用子查询或窗口函数,GROUP BY下则按组计算极值。

MAX 和 MIN 是 SQL 中最直接的极值查询工具,但它们不返回整行数据,只返回单个值;如果想查出“哪一行拥有最大/最小值”,必须配合其他语法,否则容易误以为结果就是完整记录。
MAX/MIN 只作用于单列,且忽略 NULL
这两个函数对数值、日期、字符串都有效,但行为略有差异:MAX 和 MIN 在字符串上按字典序比较,在日期上按时间先后比较。它们自动跳过 NULL 值——如果整列都是 NULL,结果就是 NULL。
常见错误是以为 SELECT MAX(price), name FROM products 能拿到最高价对应的商品名——实际 name 是随机一条(在 MySQL 5.7+ 严格模式下会报错:Expression #2 of SELECT list is not in GROUP BY clause)。
- 正确写法(仅取极值):
SELECT MAX(price) FROM products - 字符串示例:
SELECT MIN(name) FROM users返回字典序最靠前的用户名 - 日期示例:
SELECT MAX(created_at) FROM orders返回最新订单时间
查“哪一行”有极值:用子查询或窗口函数
要获取极值所在行的全部字段,不能只靠 MAX/MIN。主流做法有两种:
- 子查询方式(兼容性最好):
SELECT * FROM products WHERE price = (SELECT MAX(price) FROM products)—— 注意:如果有多个商品价格并列最高,会返回多行 - 窗口函数方式(推荐用于复杂场景):
SELECT * FROM (SELECT *, RANK() OVER (ORDER BY price DESC) AS rnk FROM products) t WHERE rnk = 1——RANK()能处理并列,ROW_NUMBER()则强制唯一编号 - MySQL 8.0+ 或 PostgreSQL 可用
ORDER BY ... LIMIT 1快速取一行,但无法处理并列情况
GROUP BY 下的 MAX/MIN 行为容易误解
一旦加了 GROUP BY,MAX/MIN 就变成每组内的极值,不是全表极值。这是合理设计,但新手常混淆上下文。
-
SELECT category, MAX(price) FROM products GROUP BY category→ 每类商品的最高价 - 若同时选非分组字段如
name,多数数据库(PostgreSQL、SQL Server)会报错;MySQL 默认开启sql_mode=ONLY_FULL_GROUP_BY后也会报错 - 想查每组中“最贵商品的完整信息”,仍需结合子查询或窗口函数,不能依赖
GROUP BY直接带出其他字段
真正麻烦的地方不在函数本身,而在于“极值所属行”这个需求天然需要关联操作——MAX 和 MIN 是聚合函数,天生丢弃行上下文。哪怕只是加个 WHERE 条件,也得确认是否真能命中目标行,尤其当存在重复极值时。

















