导读:本期聚焦于小伙伴创作的《如何用SQL语句快速取出数据表中的最大值与最小值?》,敬请观看详情。想从订单表里找出金额最高和最低的记录,却不想写两条查询分别跑?MAX与MIN作为SQL标准聚合函数,能直接在单列上返回极值,配合GROUP BY还可按分组提取。若需同时拿到最大最小及对应行信息,单用聚合会丢失其他字段,此时可用子查询或窗口函数衔接。理解聚合函数对NULL的忽略规则,能避免统计偏差。下面以MySQL与PostgreSQL为例,展示基础用法、分组提取及关联明细的常见写法与性能注意点。

在数据库查询中,提取某一列的最大与最小值是极其常见的需求,例如统计商品价格区间、查找最早与最晚的登录时间等。SQL通过聚合函数MAX和MIN提供了原生支持,但在实际业务中往往还需要连带取出极值所在行的其他字段,这就涉及子查询、窗口函数等不同写法。

如何用SQL语句快速取出数据表中的最大值与最小值?

一、MAX与MIN的基础用法

MAX函数返回指定列的最大值,MIN函数返回最小值,它们都属于SQL标准中的聚合函数。当作用于数值、日期甚至字符串类型时,数据库会按对应类型的排序规则得出结果。需要特别注意的是,MAX和MIN都会自动忽略NULL值,如果列中所有非空值都不存在,则返回NULL。

以下示例从orders表中取出订单金额的最高值与最低值:

-- 基础聚合查询,返回整表的最大最小金额
SELECT
  MAX(amount) AS max_amount,
  MIN(amount) AS min_amount
FROM orders;

这种写法最为简单,执行计划通常只需一次全表扫描或索引扫描。但若在amount列上建有B树索引,数据库优化器可能直接读取索引两端叶子节点,效率极高。不过它只能返回极值本身,无法顺带拿到下单用户、时间等关联信息。

二、按分组提取最大最小值

业务常需按类别分别看极值,例如每个商品分类的最高与最低价。此时在SELECT中使用MAX、MIN,并结合GROUP BY分组列即可。分组聚合会在每个分组内独立计算,不会跨组比较。

示例按category_id分组统计:

-- 每个分类的价格极值
SELECT
  category_id,
  MAX(price) AS highest_price,
  MIN(price) AS lowest_price
FROM products
GROUP BY category_id
ORDER BY category_id;

使用分组聚合时,SELECT列表只能出现GROUP BY列与聚合函数,若写入非分组列会引发报错或返回不确定值,这取决于数据库的配置模式。在MySQL的ONLY_FULL_GROUP_BY关闭时虽不报错,但结果并不可靠,因此应严格遵循聚合规范。

对于分组后还需筛选极值范围的场景,可用HAVING子句,例如只保留最高价大于100的分组:

SELECT
  category_id,
  MAX(price) AS highest_price
FROM products
GROUP BY category_id
HAVING MAX(price) > 100;

三、取出极值所在行的其他字段

基础聚合只能给数字,实际常需知道“价格最高的那件商品叫什么”。这时有几种典型方案。第一种是用子查询把极值算出来,再作为条件关联原表。

-- 找出价格等于最低价的商品明细
SELECT *
FROM products
WHERE price = (SELECT MIN(price) FROM products);

该写法逻辑清晰,但子查询会执行一次,若原表很大且无合适索引,可能扫描两遍。另一种写法利用窗口函数,在不聚合掉行的前提下标记极值:

-- 用窗口函数标记每行是否为价格最大或最小
SELECT
  product_name,
  price,
  CASE WHEN price = MAX(price) OVER() THEN '最高' ELSE '' END AS is_max,
  CASE WHEN price = MIN(price) OVER() THEN '最低' ELSE '' END AS is_min
FROM products;

窗口函数MAX(price) OVER()在不分组时对整个集求极值,并为每行附加比较结果。这种方式只需一遍扫描,且保留全部明细,适合报表展示。但要注意OVER()内若加PARTITION BY则变成分组内极值,使用时应明确业务含义。

四、字符串与日期类型的极值

MAX和MIN不只用于数字。对字符串按字符集排序取最大最小,对日期取最新最旧同样有效。例如查找最近注册用户:

-- 最早与最晚注册时间
SELECT
  MIN(register_time) AS first_user,
  MAX(register_time) AS last_user
FROM user_account;

在字符串场景中,若字段混杂大小写,不同数据库排序规则会影响结果,例如PostgreSQL默认区分大小写,MySQL依赖collation设置。因此在文本极值判断前,建议统一使用LOWER或指定排序规则,避免环境差异导致数据偏差。

五、性能与索引建议

当表数据量达到千万级,频繁取极值应依赖索引。对数值或时间列建B树索引后,MAX一般可转化为“索引逆序首行”,MIN转化为“索引正序首行”,复杂度接近O(1)。可用EXPLAIN观察是否出现Index Scan或Top-N操作。

若业务同时要求最大与最小,分开两个索引扫描通常比全表聚合更快;部分数据库支持在一条语句里用两个聚合,优化器也能分别走索引两端。相比之下,子查询关联原表若没命中覆盖索引,则容易产生额外开销,此时窗口函数方案在只读分析库上往往更平稳。

方案能否带明细扫描次数适用场景
基础聚合1次仅要极值数字
子查询关联2次左右取极值行且逻辑简单
窗口函数1次报表保留全量并标注

综合运用上述语句与索引策略,便能用SQL高效且准确地取出所需的最大与最小值,并灵活扩展到分组及明细查询中。

SQL聚合函数MAX_MIN修改时间:2026-08-04 20:33:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。