如何按Name分组并返回对应最大Version的完整行数据
如何按分组获取每组中最大Version对应的完整行
问题场景
现有一张包含重复Name的表,结构及数据如下:
| Name | Version | Colour |
|---|---|---|
| James | 1 | Blue |
| James | 2 | Blue |
| James | 3 | Black |
| Jill | 1 | Red |
| Jill | 2 | Blue |
| Jill | 3 | Red |
| Jill | 4 | Black |
| Jill | 5 | Red |
| Steve | 1 | Blue |
| Steve | 2 | Blue |
需要编写SQL查询,按Name分组,仅返回每组中Version最大的完整行(包含Colour字段),期望结果如下:
| Name | Version | Colour |
|---|---|---|
| James | 3 | Black |
| Jill | 5 | Red |
| Steve | 2 | Blue |
原查询的问题分析
你尝试的查询:
SELECT Name, MAX(Version), Colour FROM DB GROUP BY Name
报错是因为SQL标准要求:SELECT中的非聚合字段必须出现在GROUP BY子句中。如果将Colour加入GROUP BY,会按(Name, Colour)组合分组,导致同一个Name下不同Colour的行都被保留,无法得到仅含最大Version的目标行。
解决方案
方案1:子查询关联
先通过子查询获取每个Name对应的最大Version,再关联原表筛选对应数据行:
SELECT db.Name, db.Version, db.Colour FROM DB db INNER JOIN ( SELECT Name, MAX(Version) AS MaxVersion FROM DB GROUP BY Name ) max_ver ON db.Name = max_ver.Name AND db.Version = max_ver.MaxVersion
方案2:窗口函数(推荐)
使用ROW_NUMBER()窗口函数按Name分组,组内按Version降序排序,取排序后行号为1的记录:
SELECT Name, Version, Colour FROM ( SELECT Name, Version, Colour, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Version DESC) AS rn FROM DB ) ranked WHERE rn = 1
PARTITION BY Name:将数据按Name分组ORDER BY Version DESC:每组内按Version从大到小排序ROW_NUMBER():给每组内的行分配序号,最大Version的行序号为1
若存在同一个
Name下多个行拥有相同最大Version的情况,ROW_NUMBER()会随机保留一行;如需保留所有符合条件的行,可替换为RANK()或DENSE_RANK()函数。
内容的提问来源于stack exchange,提问作者p0ppins
相关产品推荐
相关产品推荐

