如何在多列查询中获取各分组ID最小的完整行
解决分组取最小Id对应完整行的问题
这个需求太常见啦!你碰到的问题正是GROUP BY的典型局限——因为GROUP BY要求非聚合列必须出现在分组条件里,但你要的是每个Type分组下Id最小的那一行完整数据,这时候用窗口函数或者关联查询就可以完美解决,给你几个实用的方案:
方法一:窗口函数(推荐,现代数据库通用)
用ROW_NUMBER()窗口函数给每个Type分组内的行按Id排序,筛选出排序后编号为1的行,就能保留所有列的数据:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Type ORDER BY Id ASC) AS row_num FROM your_table_name ) ranked_rows WHERE row_num = 1;
说明:
PARTITION BY Type:按Type字段把数据分成不同的组ORDER BY Id ASC:每个组内按Id从小到大排序,确保最小的Id排在第一位row_num = 1:只保留每个组里的第一行,也就是Id最小的那一行
方法二:关联子查询(兼容老版本数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.7及以前版本),可以先通过子查询算出每个Type的最小Id,再关联原表拿到完整行:
SELECT main.* FROM your_table_name main INNER JOIN ( SELECT Type, MIN(Id) AS min_id FROM your_table_name GROUP BY Type ) min_ids ON main.Type = min_ids.Type AND main.Id = min_ids.min_id;
说明:
- 子查询
min_ids先得到每个Type对应的最小Id - 用
Type和Id关联原表,精准匹配到每个Type下Id最小的那一行
方法三:EXISTS子查询
用EXISTS子句判断当前行是否是该Type下Id最小的行,逻辑更直观:
SELECT * FROM your_table_name t1 WHERE NOT EXISTS ( SELECT 1 FROM your_table_name t2 WHERE t2.Type = t1.Type AND t2.Id < t1.Id );
说明:
这个语句的逻辑是:不存在同Type且Id比当前行更小的行,那当前行自然就是该Type下Id最小的行,同样能返回完整的行数据。
内容的提问来源于stack exchange,提问作者Fernando Álvarez
相关产品推荐
相关产品推荐

