我是mySQL的新手,我想问一下当我想找到一个国家的最大预期寿命时,这个sql语句的问题是什么
SELECT Name, Max(LifeExpectancy) From world.country;
结果是:
但是,当我输入下面的SQL并进行排序时,最大LifeExpectancy不是我期望的列。
SELECT * From world.country Order By LifeExpectancy Desc;
那么我的第一个查询有什么问题?
我可以得到我对此查询的期望。
Select continent, name, max(LifeExpectancy) As max
From statworld.country
Group By name
Order By max Desc
Limit 1;
您可以从此处下载示例世界数据库: https://dev.mysql.com/doc/index-other.html
答案 0 :(得分:1)
在第一个查询中,列name
不包含在聚合函数中,也不包含在group by中,因此MySQL会为其选择一个随机值。这就是为什么你得到不正确的结果。来自Group by handling的Mysql文档:
如果ONLY_FULL_GROUP_BY被禁用,则使用MySQL扩展 GROUP BY允许选择列表,HAVING条件或ORDER BY 列表以引用非聚合列,即使列不是 功能上依赖于GROUP BY列。这会导致MySQL 接受前面的查询。在这种情况下, 服务器可以自由选择 每个组中的任何值,因此除非它们相同,否则为值 选择的是不确定的,这可能不是你想要的 。
您将在第二个查询中使用从continent
列返回的值执行相同的行为:
Select continent, name, max(LifeExpectancy) As max
From statworld.country
Group By name
Order By max Desc
Limit 1;
您应该遵循其他RDBMS(如Oracle和SQL Server)所遵循的推荐标准方式,在使用GROUP BY
时,它永远不会使用没有group by的列,也不会使用聚合函数。因此,您应该将列continent
包含在一个组中,或者使用聚合函数,以获得正确的值:
Select continent, name, max(LifeExpectancy) As max
From statworld.country
Group By name, continent
Order By max Desc
Limit 1;
答案 1 :(得分:1)
您根本不需要此查询的聚合。 MySQL中的正确查询是:
Select continent, name, LifeExpectancy
From statworld.country
Order By LifeExpectancy Desc
Limit 1;
(在其他数据库中会非常相似。更改为limit
。ANSI标准公式为fetch first 1 row only
。)
如果您可以拥有并且您想要所有国家/地区,请使用:
select sc.continent, sc.name, sc.LifeExpectancy
from statworld.country sc
where sc.LifeExpectancy = (select max(sc2.LifeExpectancy) from statworld.country sc2);