如何获得包含每个分组集的最大值的行?

我见过这个问题的一些过于复杂的变体,没有一个有好的答案。我试着把最简单的例子放在一起:

给一个这样的表,有个人、组和年龄列,你如何得到每组中年龄最大的人?(一组中平局的结果应按首字母顺序排列)

Person | Group | Age
---
Bob  | 1     | 32  
Jill | 1     | 34  
Shawn| 1     | 42  
Jake | 2     | 29  
Paul | 2     | 36  
Laura| 2     | 39  

期望结果集:

Shawn | 1     | 42    
Laura | 2     | 39  

当前回答

你也可以试试

SELECT * FROM mytable WHERE age IN (SELECT MAX(age) FROM mytable GROUP BY `Group`) ;

其他回答

with CTE as 
(select Person, 
[Group], Age, RN= Row_Number() 
over(partition by [Group] 
order by Age desc) 
from yourtable)`


`select Person, Age from CTE where RN = 1`

我的解决方案只适用于你只需要检索一个列,但我的需求是在性能方面发现的最佳解决方案(它只使用一个查询!):

SELECT SUBSTRING_INDEX(GROUP_CONCAT(column_x ORDER BY column_y),',',1) AS xyz,
   column_z
FROM table_name
GROUP BY column_z;

它使用GROUP_CONCAT以创建一个有序concat列表,然后我只将子字符串字符串到第一个。

我不会使用Group作为列名,因为它是保留字。但是,使用SQL就可以了。

SELECT a.Person, a.Group, a.Age FROM [TABLE_NAME] a
INNER JOIN 
(
  SELECT `Group`, MAX(Age) AS oldest FROM [TABLE_NAME] 
  GROUP BY `Group`
) b ON a.Group = b.Group AND a.Age = b.oldest

改进了axiac的解决方案,以避免每个组选择多行,同时还允许使用索引

SELECT o.*
FROM `Persons` o 
  LEFT JOIN `Persons` b 
      ON o.Group = b.Group AND o.Age < b.Age
  LEFT JOIN `Persons` c 
      ON o.Group = c.Group AND o.Age = c.Age and o.id < c.id
WHERE b.Age is NULL and c.id is null

采用排名法。

SELECT @rn :=  CASE WHEN @prev_grp <> groupa THEN 1 ELSE @rn+1 END AS rn,  
   @prev_grp :=groupa,
   person,age,groupa  
FROM   users,(SELECT @rn := 0) r        
HAVING rn=1
ORDER  BY groupa,age DESC,person

这个sql可以解释如下:

Select * from users, (Select @rn:= 0) r 按组别、年龄、个人排序 @prev_grp为空 @rn:= CASE WHEN @prev_grp <> groupa THEN 1 ELSE @rn+1 END 这是一个三个运算符的表达式 就像这样,rn= 1 if prev_grp != groupa else rn=rn+1 让rn=1过滤掉你需要的行