SQL分组查询如何获取多列最大值所在行的指定列值?
原SQL的核心问题
- 语法逻辑不规范:
SELECT中直接写非聚合字段G,既没有做聚合计算也没有加入GROUP BY,不同数据库执行时会随机取组内某行的G值,很容易出现空值或错配。 HAVING过滤逻辑错误:HAVING是对分组聚合后的结果做过滤,你直接写H=d1 OR I=d1 OR j=d1,这里的H、I、J是分组时随机抽取的组内单行值,不是组内所有行的匹配判断,自然匹配不到正确的行。- 函数用法错误:绝大多数数据库的
MAX()聚合函数只支持传入1个字段/表达式,你嵌套写MAX(MAX(H),MAX(I),MAX(J))传3个参数,本身就会触发执行异常,返回非预期结果;另外你列名写了小写j,大小写敏感的数据库会直接报列不存在。
正确写法
适配支持窗口函数的数据库(MySQL8.0+、PostgreSQL、SQL Server、SQLite等,目前主流环境都支持)
写法最简洁,性能也更好:
SELECT C, group_max AS d1, G FROM ( SELECT *, -- 计算按C分组后,全组H/I/J三列的最大值 MAX(GREATEST(H, I, J)) OVER (PARTITION BY C) AS group_max, -- 按组内H/I/J的最大值倒序排序,值最大的行排第1位 ROW_NUMBER() OVER ( PARTITION BY C ORDER BY GREATEST(H, I, J) DESC ) AS row_rank FROM 替换成你的实际表名 ) t -- 只取每组里值最大的第一行 WHERE row_rank = 1;
如果同一个分组内有多行同时达到H/I/J的最大值,需要把所有匹配行都返回的话,把
ROW_NUMBER()替换成RANK()即可。
适配不支持窗口函数的老版本数据库(如MySQL5.x及更早版本)
用分组聚合后关联原表的方式实现:
SELECT t1.C, t2.group_max AS d1, t1.G FROM ( -- 先按C分组,算出每组H/I/J三列的最大值 SELECT C, MAX(GREATEST(H, I, J)) AS group_max FROM 替换成你的实际表名 GROUP BY C ) t2 -- 关联回原表,找到组内三列最大值等于组最大值的行 INNER JOIN 替换成你的实际表名 t1 ON t1.C = t2.C AND GREATEST(t1.H, t1.I, t1.J) = t2.group_max;
注意事项
- 如果你的数据库不支持
GREATEST()函数(比如部分老版本Access),可以把所有GREATEST(H, I, J)替换为等价的判断逻辑:CASE WHEN H >= I AND H >= J THEN H WHEN I >= J THEN I ELSE J END - 写SQL时注意列名大小写和实际表结构一致,避免因大小写敏感触发报错。
内容的提问来源于stack exchange,提问作者yendang9423082
相关产品推荐
相关产品推荐

