聚合函数需要 GROUP BY 吗?

Posted

技术标签:

【中文标题】聚合函数需要 GROUP BY 吗?【英文标题】:Is GROUP BY needed for aggregation function? 【发布时间】:2018-11-07 23:29:02 【问题描述】:

问题:

给定 CITY 和 COUNTRY 表,查询所有的名称 各大洲(COUNTRY.Continent)及其各自的平均城市 人口 (CITY.Population) 向下舍入到最接近的整数。

注意:CITY.CountryCode 和 COUNTRY.Code 是匹配的键列。做 在您的输出中不包括没有城市的大陆。

我的解决方案:

SELECT COUNTRY.CONTINENT, FLOOR(AVG(CITY.POPULATION)) FROM COUNTRY INNER JOIN CITY ON COUNTRY.CODE=CITY.COUNTRYCODE

但这似乎不起作用,直到我添加一个 GROUP BY 语句 更新解决方案:

SELECT COUNTRY.CONTINENT, FLOOR(AVG(CITY.POPULATION)) FROM COUNTRY INNER JOIN CITY ON COUNTRY.CODE=CITY.COUNTRYCODE GROUP BY COUNTRY.CONTINENT

为什么会这样?为什么不显示新的 INNER JOIN 表的平均人口值? 我知道这会给我错误的答案,即它将显示每个大陆相同的平均人口值。但我的疑问是为什么我不添加 GROUP BY 语句时它不起作用。

抛出的错误:

第 1 行的错误 1140 (42000):在没有 GROUP BY 的聚合查询中, SELECT 列表的表达式 #1 包含非聚合列 'run_y53padyvlle.COUNTRY.continent';这与 sql_mode=only_full_group_by

【问题讨论】:

mysql 文档中也解释了这种行为dev.mysql.com/doc/refman/8.0/en/group-by-handling.html 因为这个和sql_mode=only_full_group_by不兼容 【参考方案1】:

问题不在于AVG()。你可以这样做:

SELECT FLOOR(AVG(ci.POPULATION))
FROM COUNTRY c INNER JOIN
     CITY ci
     ON c.CODE = ci.COUNTRYCODE;

这会返回一行,即数据库中所有城市的总体平均人口。

问题是当你这样做时:

SELECT c.CONTINENT, FLOOR(AVG(ci.POPULATION)) 
. . . 

CONTINENT 部分未聚合。 SQL 引擎需要知道如何处理它。把钥匙放在GROUP BY

GROUP BY c.CONTINENT

表示您希望CONTINENT 中的每个值在结果集中占一行。

【讨论】:

以上是关于聚合函数需要 GROUP BY 吗?的主要内容,如果未能解决你的问题,请参考以下文章

GROUP BY 子句必须与聚合函数一起使用?

为啥 CROSS APPLY 与列和聚合函数需要 Group by

mysql 可以group by 两个字段吗

聚合函数 和 group by

没有聚合功能的 GROUP BY 子句有啥原因吗?

为啥没有聚合函数的选择列需要成为 MySQL 中 Group by 子句的一部分?