SQL Server查询:获取按C2分组后C1最大值对应的所有行
解决SQL Server中按分组取最大值对应所有行的问题
这需求我平时写业务逻辑时经常遇到,给你分享几个实用的解法,都能精准返回你要的结果:
方法一:子查询关联法
先通过子查询找出每个C2分组对应的最大C1值,再关联原表筛选出符合条件的行:
SELECT t.C1, t.C2, t.C3 FROM YourTable t INNER JOIN ( -- 先获取每个C2组的最大C1 SELECT C2, MAX(C1) AS MaxC1 FROM YourTable GROUP BY C2 ) sub ON t.C2 = sub.C2 AND t.C1 = sub.MaxC1 -- 按需求排序,可选 ORDER BY t.C2, t.C1, t.C3;
这个方法逻辑清晰,适合新手理解,关联的方式在数据量不大时效率也不错。
方法二:窗口函数RANK法
利用RANK()窗口函数给每个C2分组内的行按C1降序排名,取排名为1的行(也就是C1最大的那些记录):
WITH RankedData AS ( SELECT C1, C2, C3, -- 按C2分组,C1降序排名,相同C1的行排名一致 RANK() OVER (PARTITION BY C2 ORDER BY C1 DESC) AS rnk FROM YourTable ) SELECT C1, C2, C3 FROM RankedData WHERE rnk = 1 ORDER BY C2, C1, C3;
这里如果用DENSE_RANK()效果是一样的,区别在于当分组内有多个相同的最大值时,两者都会保留所有对应行,而如果用ROW_NUMBER()则会给每行分配唯一序号,可能会误删相同最大值的行,所以这里不推荐用ROW_NUMBER()。
方法三:MAX()窗口函数标记法
直接在每行计算出对应C2分组的最大C1值,再筛选出C1等于该最大值的行:
SELECT C1, C2, C3 FROM ( SELECT C1, C2, C3, -- 计算当前行所在C2组的最大C1 MAX(C1) OVER (PARTITION BY C2) AS MaxC1InGroup FROM YourTable ) t WHERE C1 = MaxC1InGroup ORDER BY C2, C1, C3;
这个方法逻辑最直观,不需要额外的排名计算,适合快速编写查询。
小提示
如果你的表数据量较大,建议给C2和C1字段建立联合索引,这样能大幅提升这几种查询的执行效率。
内容的提问来源于stack exchange,提问作者StackUser
相关产品推荐
相关产品推荐

