【问题标题】:Finding the record with maximum value in SQL在 SQL 中查找具有最大值的记录
【发布时间】:2012-01-04 00:02:56
【问题描述】:

我有下表:

Class, Name, Score
1, Anna, 34
1, Andy, 80
2, Brooke, 90
2, Brad, 70
3, Charles, 67
3, Christina, 66

如何在每个“班级”中找到“分数”最高的“姓名”?

所需输出:

Class, Name, Score
1, Andy, 80
2, Brooke, 90
3, Charles, 67

这是为 MySQL 准备的。

【问题讨论】:

  • 看起来像家庭作业。提示是:使用 group by 和 max
  • 我添加了greatest-n-per-group标签,这个问题在StackOverflow上很受欢迎。按照该标签链接获取许多解决方案。
  • @Steven Nope。我同意这是一个(匆忙创建的)玩具问题。实际问题要复杂得多。但我被困在这部分问题上。
  • 抱歉 ElKamina,当属性反映典型的学校作业名称时,有时很难区分。
  • @Steven 我仍然有兴趣了解您的解决方案,因为它看起来比提供的解决方案更简单。

标签: mysql sql max greatest-n-per-group


【解决方案1】:
WITH ClassScores AS
(
    SELECT 1 AS class, 'Anna' AS name, 34 AS score 
    UNION
    SELECT 1, 'Andy', 80  
    UNION
    SELECT 2, 'Brooke', 90  
    UNION
    SELECT 2, 'Brad', 70  
    UNION
    SELECT 3, 'Charles', 67  
    UNION
    SELECT 3, 'Christina', 66 
)

SELECT C1.Class, C1.Name, C1.Score
  FROM ClassScores AS C1
  JOIN (SELECT Class, MAX(Score) AS MaxScore
          FROM ClassScores
         GROUP BY Class
       ) AS C2
    ON C1.Class = C2.Class
   AND C1.Score = C2.MaxScore
 ORDER BY C1.Class;

【讨论】:

  • 谢谢,@AbeMiessler。我注意到,如果两个(或更多)人在一个班级中获得相同的最高分数,那么您将获得该班级的几行 - 每个得分最高的人一个。这可能比随机选择谁被选为特定班级的原型要好 - 或者您需要额外的标准来区分假定的告别演说者。
  • 感谢添加 CTE,它使这些答案更有价值。
  • 它有效,但有两个警告。一,需要两次通过。第二,正如您自己所指出的,如果出现平局,它会返回同一类的多个条目。我是 SQL 新手,我发现 MySQL 无法通过单个(通过)查询来完成如此简单的任务,这让我感到震惊:(
  • 它不能一次完成,因为建立最大分数需要一次通过,然后找到相应的行需要另一次 - 在 SQL 中。如果您使用的是 C-ISAM 或类似的软件包,如果有适当的索引可供使用,您可能会做得更好,但您必须小心维护该索引的成本与您实际使用的数量它。 (适当的索引是指“类,分数”上的索引,之后可以选择“名称”,这将为您提供仅索引查询)。但这需要一些适度的编码技能才能做到这一点; SQL 更简单。
【解决方案2】:

另一种方式 - 如果ClassScores 有一个(隐藏的)PRIMARY KEY

SELECT 
    cs.Class
  , cs.Name
  , cs.Score
FROM 
      ( SELECT DISTINCT Class 
        FROM ClassScores 
      ) AS csd
  JOIN 
      ClassScores AS cs
    ON cs.PK = 
       ( SELECT csm.PK
         FROM ClassScores csm
         WHERE csm.Class = csd.Class
         ORDER BY csm.Score DESC
         LIMIT 1
       )

【讨论】:

    【解决方案3】:

    使用 UNION 然后您可以单独使用三个 select 语句。它会很好地清理代码。

    试试..

    select class, name, max(score) as "Score" from yourTable where class=1
    UNION
    select class, name, max(score) as "Score" from yourTable where class=2
    UNION
    select class,name,max(score) as "Score" from yourTable where class=3
    

    【讨论】:

    • 我有 1000 个这样的“类”,这种方法对我的情况来说很棘手。
    • 哈哈好吧,我根据给出的小数据给了你答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多