【问题标题】:How to select a maximum value row in mysql table如何在mysql表中选择最大值行
【发布时间】:2013-06-26 11:09:40
【问题描述】:

我有下表

表结构:

CREATE TABLE IF NOT EXISTS `people` ( 
`name` varchar(10) NOT NULL, 
`age` smallint(5) unsigned NOT NULL, 
PRIMARY KEY (`name`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

插入一些值:

INSERT INTO `people` (`name`, `age`) VALUES 
('bob', 13), 
('john', 25), 
('steve', 8), 
('sue', 13); 

执行的查询:

SELECT MAX(  `age` ) ,  `name` FROM  `people` WHERE 1

预期结果:

25, John

生成的结果

25, bob

我们可以通过使用这个查询来实现这一点

SELECT `age`,  `name` FROM  `people` ORDER BY age DESC LIMIT 1

问题1:我在这里犯了什么错误,为什么这个MAX函数没有返回相关的行信息?

问题2:用MAX函数还是ORDER BY子句哪个好用?

【问题讨论】:

  • 对于这个简单的例子,答案显然是 ORDER BY。对于更复杂的问题 - 所谓的 GROUPWISE MAX 查询,这是一个常见问题解答,并且已经提供了无数答案。

标签: mysql performance


【解决方案1】:

问题1:我在这里犯了什么错误,为什么这个MAX函数没有返回相关的行信息?

您需要阅读group by 子句。

MySQL 比它应该的要宽松得多,在这个过程中引入了混乱。基本上,任何没有聚合的列都应该包含在group by 子句中。但是 MySQL 语法糖允许“忘记”列。当你这样做时,MySQL 从它分组的集合中吐出一个任意值。在你的情况下,集合中的第一行是bob,所以它返回。

问题2:提高性能MAX函数还是ORDER BY子句,哪个好用?

您的第一条语句(使用max() 而不使用group by)完全不正确。

如果您想要最老的用户之一,order by age desc limit 1 是正确的方法。

如果你想要所有最老的用户,你需要一个子选择:

SELECT p.* FROM people p WHERE p.age = (select max(subp.age) from people subp);

【讨论】:

  • 我同意哪一个可以提高性能,Order By 子句或子查询
  • 要么——它们给出不同的结果。为了提高性能,您需要在age 上建立索引。
【解决方案2】:

试试这个

SELECT age, name FROM  `people` where age = (SELECT max(age) FROM  people)

【讨论】:

  • 我同意你的回答,但是哪一个可以提高性能,Order By 子句或子查询
  • 如果您在表中使用任何索引,则使用 Order by 否则子查询优于 Order by 子句谢谢
【解决方案3】:

另一个不使用聚合函数和分组的解决方案:

SELECT * FROM people ORDER BY age DESC LIMIT 1

【讨论】:

    【解决方案4】:

    我在这里犯了什么错误,为什么这个 MAX 函数没有返回相关的行信息?

    MAX 正在返回正确的值 - 但您选择的另一列只是给您一个“随机”值。

    选择不属于 GROUPing 的列(我认为隐式 GROUP BY 在这里完成,因为您使用聚合函数)在严格的 SQL 中是非法的 - 但是 MySQL 会忽略这一点(取决于服务器配置),并为您提供在这种情况下,来自“随机”行的值。


    此处描述了替代方法:The Rows Holding the Group-wise Maximum of a Certain Column

    【讨论】:

      【解决方案5】:

      MAX 是aggregate function。这意味着 MySQL 将所有记录分组并将它们视为结果集中的一条。由于您没有说明如何对名称列进行分组,因此结果可能出乎意料。 ORDER BY 是实现预期结果的完美方式。只是不要忘记在年龄上添加index,这样性能就不会随着表的增长而受到影响。

      【讨论】:

        【解决方案6】:

        问题 1: 如果你真的想使用 MAX() 你可以试试这个 SELECT age, name FROM people WHERE age IN (SELECT MAX(age) FROM people);

        问题 2: 我认为这取决于我在问题 1 中的建议,您执行两次查询,但是在您提供的ORDER BY 解决方案中,数据库执行了类似的过程。

        【讨论】:

          【解决方案7】:

          有一个有趣的替代方案只适用于 MySql!

          SELECT `Name`, `Age` FROM 
          (SELECT `Name`, `Age`, 1 AS `foo`
          FROM `People`
          ORDER BY `Age` DESC) AS `x`
          GROUP BY `foo`
          

          这是因为 MySql 在给定列上没有应用聚合函数时返回第一行

          这里是链接:http://tominology.blogspot.com.br/2014/10/sql-row-with-max-value.html

          【讨论】:

            猜你喜欢
            • 2013-04-03
            • 2021-05-03
            • 2021-09-28
            • 2016-02-16
            • 1970-01-01
            • 1970-01-01
            • 2012-03-16
            • 2021-07-23
            • 2013-10-20
            相关资源
            最近更新 更多