【发布时间】:2013-12-02 02:04:04
【问题描述】:
我想选择人口最多的国家。这是我的查询:
SELECT continent, name, population FROM country HAVING population = MAX(population);
它以某种方式返回 0 行。
如果我使用嵌套查询,它可以工作:
SELECT continent, name, population FROM country WHERE population = (SELECT MAX(population) FROM country);
所以我的问题是:第一个查询有什么问题?
PS:你可以在这里下载数据库: http://dev.mysql.com/doc/index-other.html
好吧,我想我终于弄清楚了整个过程。以下是它的工作原理以及替代建议/解决方案不起作用的原因:
(首先,正如“Dan Bracuk”在他的回答中所说,我们必须将 GROUP BY 与 HAVING 结合起来,并在 SELECT 语句的开头添加聚合函数)
让我们一步一步来试试这个:
SELECT continent, name, population, MAX(population) FROM country;
这为我们生成了在末尾附加 MAX(pop) 的第一行:
“North America”、“Aruba”、“103000”、“1277558000”
所以 MAX(population) 只是一个条目,因此它将行号限制为 1,并且因为我添加了大陆、名称、人口列,mysql 只从表中选择第一行。
所以如果我现在写下来:
SELECT continent, name, population, MAX(population) FROM country HAVING population = MAX(population);
我得到 0 行,因为 103000 不等于 1277558000。
如果我使用:
SELECT continent, name, population, MAX(population) FROM country GROUP BY name;
例如,我得到了所有国家的列表,其中每行 MAX(population) = population。
所以另外添加“HAVING population = MAX(population)”没有任何效果,因为它已经是真的了。
我希望我理解正确,并且可以澄清其他想知道为什么其他解决方案不起作用的人。
【问题讨论】:
-
这不是
HAVING without GROUP BY问题的例子吗?如果是这样,那么这是一个评估问题。 -
嗯,我认为你是对的。但是,评估问题是什么意思?
-
我对您的查询失败的原因的解释可能是错误的,但我可以对“没有
GROUP BY”问题有所了解。HAVING在SELECT之前和GROUP BY之后进行评估。想象一下你的结果被慢慢过滤了。FROM先行动,必要时加入表格。接下来,WHERE过滤表中的结果。这是对您很重要的部分:GROUP BY会将这些行分组,然后HAVING将根据您的条件删除所有不合格的组。SELECT现在将进入并处理剩余的列表。这意味着HAVING无法在您的SELECT上工作。 -
上述情况很重要,因为您正在做两件事:您在
population上的引用,但它还不能被引用。此外,您没有GROUP BY可以“强制”population出现。我不是 SQL 专家,因此您的查询问题可能不正确。然而,评估的逻辑似乎支持这一点。 -
@moller1111 我已经编辑了我的答案,并认为它完全回答了你的问题。