当前位置: 首页 > 知识库问答 >
问题:

获取每组分组SQL结果的最大值记录

戎志勇
2023-03-14

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

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

给出一个类似下面的表,包含person,group,和age列,如何得到每个组中最年长的人?(一组内的平局应给出第一个按字母顺序排列的结果)

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  

共有2个答案

曾典
2023-03-14

正确的解决方案是:

SELECT o.*
FROM `Persons` o                    # 'o' from 'oldest person in group'
  LEFT JOIN `Persons` b             # 'b' from 'bigger age'
      ON o.Group = b.Group AND o.Age < b.Age
WHERE b.Age is NULL                 # bigger age not found

它将o中的每一行与b中的所有行匹配,这些行在列group中具有相同的值,而在列age中具有更大的值。O中的任何行不具有Age列中其组的最大值,都将匹配B中的一个或多个行。

左联接使它将组中最年长的人(包括组中单独的人)与b中充满null的行(“组中没有最大年龄”)相匹配。
使用内联接使这些行不匹配,并且将忽略它们。

where子句仅保留从b提取的字段中具有nulls的行。他们是每组中年龄最大的人。

SQL反模式:避免数据库编程的陷阱》一书中解释了这种解决方案和许多其他解决方案

酆景辉
2023-03-14

在MySQL中有一种超简单的方法来实现这一点:

select * 
from (select * from mytable order by `Group`, age desc, Person) x
group by `Group`

这是因为在mysql中允许不聚合非GROUP-BY列,在这种情况下,mysql只返回第一行。解决方案是首先对数据进行排序,使每组中所需的行位于第一位,然后按所需值的列进行分组。

您可以避免尝试查找max()等的复杂子查询,还可以避免在有多个具有相同最大值的行时返回多个行的问题(其他答案会这样做)

注意:这是一个只支持MySQL的解决方案。我知道的所有其他数据库都会抛出一个SQL语法错误,带有消息“non aggregated columns are not list in the group by子句”或类似的信息。因为这个解决方案使用了未记录的行为,所以如果MySQL的未来版本改变了这个行为,比较谨慎的人可能希望包含一个测试来断言它仍然可以工作。

自5.7版以来,SQL-MODE设置默认包含only_full_group_by,因此要使其正常工作,您必须不具有此选项(编辑服务器的选项文件以删除此设置)。

 类似资料:
  • 问题内容: 如何获得包含每个分组集最大值的行? 我在这个问题上看到了一些过于复杂的变体,但都没有一个很好的答案。我尝试将最简单的示例放在一起: 给定下面的表格,其中包含“人员”,“组”和“年龄”列,您将如何获得每个组中年龄最大的人?(组内的平局应该给出第一个字母顺序的结果) 所需的结果集: 问题答案: 在mysql中有一种超简单的方法: 这工作,因为在MySQL中你被允许 不 聚集非组逐列,在这种

  • 问题内容: 以下是最简单的示例,尽管任何解决方案都应能够扩展到需要n个顶级结果的地方: 给定下面的表格,其中包含“人员”,“组”和“年龄”列,您将如何 获得每个组中 年龄 最大的2个人? (组内的关系不应产生更多结果,而应按字母顺序给出前两个) 所需的结果集: 注意: 这个问题建立在先前的问题上- 获取每组分组的SQL结果的最大值的记录 -用于从每组中获取一个顶行,并且从@Bohemian那里收到

  • 问题内容: 怎么做? 该问题的原标题是“ 在带有子查询的复杂查询中使用等级(@Rank:= @Rank + 1)-可以吗? ”,因为我一直在寻找使用等级的解决方案,但是现在我看到Bill所发布的解决方案是好多了。 原始问题: 我正在尝试组成一个查询,该查询将从给定定义顺序的每个组中获取最后一条记录: 表达式通常用于等级,但对我来说,在2个子查询中使用时,它看起来可疑,但仅初始化一次。这样行吗? 其

  • 我有一个数据帧,我根据-列进行分组。对于每个组,我想得到包含最大值的行(整行,而不仅仅是值)。我能够做到这一点,首先获得每个组的最大值,然后创建一个过滤器数组,然后在原始数据帧上应用过滤器。像这样, 这个解决方案是可行的,但不知何故似乎过于繁琐。有人知道更好的方法吗?最好是一条线。关于潜在的重复,我稍后会处理这些:)

  • 问题内容: 我正在尝试编写一个查询,每天从价格明细表中获取每个商品的最低和最高价格。 在价格明细表中,每天设置多次价格,因此同一日期有很多记录。因此,我想要一个表,其中每个日期都有一行,然后将该表连接到同一张表,因此对于每个不同的日期,我都需要最小值和最大值。 SQL查询 概括 餐桌在同一天设定了许多价格。想要每个交易所报价的每天的最小值和最大值。 谢谢 问题答案: 一个简单的应该工作: 不知道为

  • 问题内容: 我有一张表格,试图从中检索每种证券的最新头寸: 桌子: 我查询创建表: 我一直在弄乱基于此页面的查询版本,但似乎无法获得想要的结果。 这是我一直在尝试的方法: 但这只是返回我: 我正在尝试获取每个证券的最大/最新购买日期,因此结果将为每个证券具有最新购买日期的一行。任何帮助是极大的赞赏。 编辑:头寸的ID必须与最大购买日期一起返回。 问题答案: 您可以使用此查询。您可以节省75%的时间