导读:本期聚焦于小师妹创作的《SQL查询多列最大值怎么写?聚合函数组合技巧详解》,敬请观看详情。想在SQL里一次性取出多个列中的最大值,却只知道MAX只作用于单列?GREATEST与MAX各有分工:MAX是聚合函数,用来在多行记录之间比较,GREATEST则是标量函数,用来在同行的多个列之间挑最大值。本文详细讲解两种函数的原理差异、具体语法和典型用法,包括处理NULL值的COALESCE技巧、跨行跨列同时取最大值的组合写法,以及不同数据库(MySQL、SQL Server、Oracle、PostgreSQL)中的兼容方案,配合可运行的示例代码,帮助你彻底掌握多列最大值的查询思路。

在日常数据查询中,我们经常会遇到这样的需求:一张表里存了语文、数学、英语三科成绩,需要找出每个学生三科中的最高分;或者一张库存表里有多个仓库的库存数量,需要取每个商品在所有仓库中的最大库存。这类问题的本质是在多个列之间比较取最大值,而很多人第一反应是使用MAX函数,结果发现查出来的结果不对。这篇文章就来详细讲解SQL中查询多列最大值的几种写法,以及聚合函数的组合使用技巧。

SQL查询多列最大值怎么写?聚合函数组合技巧详解

一、先弄清楚:MAX和GREATEST的本质区别

要正确写出多列最大值查询,第一步是分清两个容易混淆的函数:MAXGREATEST。很多人查不出期望结果,根本原因就是把这两者搞混了。

MAX是一个聚合函数(Aggregate Function),它的作用对象是某一列的多行数据。也就是说,MAX会把一整列的值收集起来,然后返回其中最大的那一个,比如MAX(score)返回的是所有学生中某一科的最高分。聚合函数会把多行压缩成一行,所以经常会配合GROUP BY使用。

GREATEST是一个标量函数(Scalar Function),也叫行级函数,它的作用对象是同一行内的多个列或多个值GREATEST(a, b, c)会比较同一行里a、b、c三个列的值,返回其中最大的。它不会压缩行数,输入多少行就输出多少行。

简单总结一句话:MAX是纵向比较(列内跨行),GREATEST是横向比较(行内跨列)。查多列最大值,用GREATEST才是对路的。

二、GREATEST函数的基本用法与NULL陷阱

以学生成绩表为例,表结构如下:

-- 创建成绩表示例
CREATE TABLE student_score (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    chinese INT,
    math INT,
    english INT
);

INSERT INTO student_score VALUES (1, '张三', 85, 92, 78);
INSERT INTO student_score VALUES (2, '李四', 90, 66, 88);
INSERT INTO student_score VALUES (3, '王五', 72, 95, 60);

如果要查每个学生三科中的最高分,直接使用GREATEST即可:

SELECT
    name,
    chinese,
    math,
    english,
    GREATEST(chinese, math, english) AS max_score
FROM student_score;

这条查询会为每一行返回一个最大值,比如张三的结果是92,李四是90。写法非常简洁,一行SQL就搞定了。

但是这里有一个非常经典的坑:NULL值的处理。在MySQL和Oracle中,只要GREATEST的任意一个参数为NULL,整个结果就会直接返回NULL。比如某个学生的英语成绩缺考记为NULL,那么他的三科最高分就会变成NULL,这显然不符合业务预期。解决方法是用COALESCEIFNULL把NULL先替换成一个极小值:

SELECT
    name,
    GREATEST(
        COALESCE(chinese, 0),
        COALESCE(math, 0),
        COALESCE(english, 0)
    ) AS max_score
FROM student_score;

这样即使某科缺考,也能正确算出其他科目中的最高分。需要注意的是,PostgreSQL的行为和MySQL不同,PostgreSQL的GREATEST会直接忽略NULL参数,只比较非NULL的值,只有当所有参数都是NULL时才返回NULL。所以跨数据库迁移时要特别留意这个差异。

三、跨行又跨列:聚合函数与GREATEST的组合技巧

实际业务中还有一种更复杂的需求:既要跨列比较,又要跨行聚合。比如要查整张表中所有学生、所有科目里的全局最高分,就可以把MAX和GREATEST嵌套起来用:

SELECT MAX(GREATEST(chinese, math, english)) AS global_max
FROM student_score;

这个写法的执行逻辑分两步:先由内层的GREATEST算出每个学生的个人最高分,再由外层的MAX在这些个人最高分中挑出最大的一个。内外层各司其职,语义非常清晰。

再进一步,如果既要看每个班级的最高分,又要看全局排名,可以结合GROUP BY使用:

SELECT
    class_id,
    MAX(GREATEST(chinese, math, english)) AS class_max
FROM student_score
GROUP BY class_id;

这种嵌套组合的思路可以推广到很多场景,比如取每个订单在多个渠道价格中的最低价(用LEAST),再统计全局最低价的平均值等等。核心技巧就是:标量函数负责行内运算,聚合函数负责行间汇总,两者按照执行顺序正确嵌套即可。

四、SQL Server等不支持GREATEST的替代方案

GREATEST虽然好用,但并不是所有数据库都支持。老版本的SQL Server(2022之前)就没有这个函数,SQL Server 2022才开始原生支持。在不支持的情况下,有几种常见的替代写法。

第一种是使用CASE WHEN逐个比较:

SELECT
    name,
    CASE
        WHEN chinese >= math AND chinese >= english THEN chinese
        WHEN math >= english THEN math
        ELSE english
    END AS max_score
FROM student_score;

这种写法兼容性最好,任何数据库都能跑,缺点是列数多的时候条件会变得很长,维护起来比较麻烦,而且要小心处理NULL参与比较时的三值逻辑问题。

第二种是利用UNPIVOT或者行转列的思路,把多列数据转成多行,再用MAX聚合:

SELECT name, MAX(score) AS max_score
FROM (
    SELECT name, chinese AS score FROM student_score
    UNION ALL
    SELECT name, math AS score FROM student_score
    UNION ALL
    SELECT name, english AS score FROM student_score
) t
GROUP BY name;

这种写法的好处是逻辑统一,无论多少列都是同样的模式扩展,而且天然规避了NULL的问题(NULL在MAX聚合中会被忽略)。缺点是子查询会扫描多次表,数据量大时性能不如GREATEST。

最后给一个选择建议:如果数据库支持GREATEST,优先用它,简洁高效;遇到NULL记得配合COALESCE处理;如果需要跨库兼容或者列数不固定,再考虑UNION ALL转行的方案。掌握这几个技巧之后,多列最大值的查询就再也没有难点了。

SQL多列最大值GREATEST函数聚合函数修改时间:2026-09-07 02:44:27

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