MySQL按id、group分组取tval最大值、重复值取较小timel的SQL实现
符合要求的MySQL分组查询实现方案
核心实现逻辑
按id、group字段完成分组划分后,对组内记录遵循两个优先级排序规则取第一条:
- 优先取
tval数值更大的记录(即每组最大tval) - 若多条记录tval并列最大,取其中
timel数值更小的记录
方案1:MySQL 8.0及以上版本(推荐,逻辑更清晰)
使用窗口函数直接完成组内排序,可读性强、易扩展,后续调整排序规则只需修改窗口内的ORDER BY子句即可:
WITH ranked_sample AS ( SELECT id, timel, `group`, tval, ROW_NUMBER() OVER ( -- 按要求的分组字段划分子集 PARTITION BY id, `group` -- 组内排序:tval降序取最大值,同值时timel升序取最小值 ORDER BY tval DESC, timel ASC ) AS row_rank FROM sample ) -- 取每个子集排序后的第一条即为目标结果 SELECT id, timel, `group`, tval FROM ranked_sample WHERE row_rank = 1;
方案2:兼容MySQL 5.x等低版本环境
如果环境不支持窗口函数、CTE语法,可通过「先查每组最大tval、再关联取最小timel」的逻辑实现,同时适配了MySQL 5.7+默认开启的ONLY_FULL_GROUP_BY模式,不会出现语法报错:
SELECT s.id, -- 同最大tval的多条记录中取最小timel MIN(s.timel) AS timel, s.`group`, s.tval FROM sample s -- 关联出每个(id, group)分组下的最大tval值 INNER JOIN ( SELECT id, `group`, MAX(tval) AS group_max_tval FROM sample GROUP BY id, `group` ) max_t ON s.id = max_t.id AND s.`group` = max_t.`group` AND s.tval = max_t.group_max_tval GROUP BY s.id, s.`group`, s.tval;
执行结果验证
基于提供的测试数据,两个方案的输出均完全符合预期:
| id | timel | group | tval |
|---|---|---|---|
| 3 | 6 | a | 3.222 |
| 4 | 0.7 | a | 2.322 |
内容的提问来源于stack exchange,提问作者Rudra
相关产品推荐
相关产品推荐

