You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 5.7 按value1分组取每组value2最高对应行的SQL实现

MySQL 5.7 分组取最大值对应整行的实现

MySQL 5.7 默认开启ONLY_FULL_GROUP_BY严格语法校验,直接用GROUP BY value1搭配聚合函数是无法直接带出value3字段的,会触发语法报错,下面是两种可直接落地、结果和预期完全匹配的写法:

写法1:关联聚合子查询(性能最优,适合大表场景)

先聚合算出每个value1分组里的最大value2值,再和原表做双字段等值关联,匹配出对应整行数据,不会触发严格模式校验,也不需要对全表数据做额外排序,大表上的执行效率远高于其他实现方式:

SELECT t.value1, t.value2, t.value3
FROM `values` t
INNER JOIN (
    SELECT value1, MAX(value2) AS max_val2
    FROM `values`
    GROUP BY value1
) group_max
  ON t.value1 = group_max.value1 
 AND t.value2 = group_max.max_val2;

注意点:如果同一value1分组下存在多行value2等于最大值,这种写法会返回所有匹配的行。如果需要强制只保留单行,可以根据业务补充额外的排序去重规则。

写法2:用户变量实现组内行排名(扩展性更强)

如果后续需要调整排序规则(比如同value2下取value3最大的行、或者取最早录入的行),可以用MySQL 5.7原生支持的会话变量给组内行打排名标记,直接过滤排名为1的行即可:

SELECT value1, value2, value3
FROM (
    SELECT
        raw.*,
        -- 相同value1的组内行号累加,组切换时行号归1
        @row_rank := IF(@last_group = raw.value1, @row_rank + 1, 1) AS rn,
        @last_group := raw.value1
    FROM `values` raw,
         -- 初始化会话变量
         (SELECT @row_rank := 0, @last_group := '') var_init
    -- 先按分组字段、排序字段排好序,保证排名计算逻辑正确
    ORDER BY raw.value1, raw.value2 DESC
) ranked
WHERE rn = 1;

两种写法执行后得到的结果完全匹配预期输出:

value1value2value3
foo12anything3
bar18anything5
baz100something0

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 04:57:05