我有下表
表格结构:
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子句?
答案 0 :(得分:21)
问题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);
答案 1 :(得分:11)
试试这个
SELECT age, name FROM `people` where age = (SELECT max(age) FROM people)
答案 2 :(得分:8)
另一种不使用聚合函数和分组的解决方案:
SELECT * FROM people ORDER BY age DESC LIMIT 1
答案 3 :(得分:3)
我在这里弄错了为什么这个MAX函数没有返回相关的行信息?
MAX返回正确的值 - 但您选择的另一列只会为您提供“随机”值。
选择不属于GROUPing的列(我认为隐式GROUP BY在这里完成,因为你使用了聚合函数)在严格的SQL中是非法的 - 但MySQL忽略了它(取决于服务器配置),并给你一个在这种情况下来自“随机”行的值。
此处描述了替代方法:The Rows Holding the Group-wise Maximum of a Certain Column
答案 4 :(得分:0)
MAX是aggregate function。这意味着MySQL将所有记录分组并将它们视为结果集中的记录。由于您没有说明如何对名称列进行分组,因此结果可能是意外的。 ORDER BY是实现理想结果的完美方式。只是不要忘记在年龄上添加index,这样随着表格的增长,性能不会受到影响。
答案 5 :(得分:0)
问题1:
如果你真的想使用MAX()
你可以试试这个
SELECT age, name FROM people WHERE age IN (SELECT MAX(age) FROM people);
问题2:
我认为这取决于我在问题1中的建议,您执行了两次查询,但在您提供的ORDER BY
解决方案中,数据库执行了类似过程的操作。
答案 6 :(得分:0)
有一个有趣的替代方案仅适用于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