You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何仅聚合一个SELECT表达式时,需对所有SELECT项分组/聚合?

关于SQL聚合函数与GROUP BY的疑问解答

核心逻辑:SQL的聚合规则要求明确关联关系

当你在SELECT语句中同时使用非聚合列(比如station_id)和聚合函数(比如AVG())时,数据库必须明确知道这两类数据的对应逻辑,否则就会抛出语法错误。


1. 为什么单独用AVG()不会报错?

当SELECT里只有聚合函数AVG(num_bikes_available)时,这是全局聚合:数据库会计算整个表的num_bikes_available平均值,最终返回1行结果,逻辑完全明确,所以可以正常运行。

示例代码:

SELECT
  AVG(num_bikes_available)
FROM
  `bigquery-public-data.new_york_citibike.citibike_stations`

查询结果:

f0_
13.249537892791142

2. 为什么加station_id不加GROUP BY会报错?

station_id是表中的非聚合列,原表有多少行,就会有多少个station_id(可能重复);而AVG()默认是全局聚合,只返回1行结果。

数据库无法判断你的需求:

  • 是要按每个station_id分组,计算每个站点自己的单车数量平均值?
  • 还是要给每一个station_id都配上整个表的全局平均值?

SQL语法规则要求必须通过GROUP BY或聚合函数来明确这个逻辑,所以会报错:

SELECT list expression references column station_id which is neither grouped nor aggregated at [2:3]


3. 为什么GROUP BY station_id能解决报错?

GROUP BY station_id告诉数据库:把表中的数据按station_id分组,每个组内单独计算AVG(num_bikes_available)。这样每个station_id对应自己组的平均值,结果行数和不同的station_id数量一致,逻辑清晰,符合SQL语法要求。

示例代码:

SELECT
  station_id,
  AVG(num_bikes_available)
FROM
  `bigquery-public-data.new_york_citibike.citibike_stations`
GROUP BY
  station_id

不过这个查询得到的是每个站点自身的单车数量平均值,和你想要的全局平均值结果不同。


4. 为什么子查询能得到你想要的结果?

你使用的子查询是标量子查询:它会先独立计算出整个表的全局平均值(返回一个单一值),然后数据库会自动把这个值和原表的每一行station_id做关联——相当于给每一行的station_id都“复制”同一个全局平均值,此时SELECT中的station_id是原表的每行数据,子查询结果是固定值,两者的行数匹配(原表有N行,子查询的单一值会重复N次),完全符合SQL的语法规则,所以可以正常运行并得到你想要的结果。

示例代码:

SELECT
  station_id,
  (SELECT
    AVG(num_bikes_available)
  FROM
    `bigquery-public-data.new_york_citibike.citibike_stations`)
FROM
  `bigquery-public-data.new_york_citibike.citibike_stations`

查询结果(示例):

station_idf0_
1bb1af93-b433-4da7-8054-009c85f7755a13.249537892791142
c638ec67-9ac0-416f-944f-61992614493113.249537892791142
66de0cab-0aca-11e7-82f6-3863bb44ef7c13.249537892791142

内容的提问来源于stack exchange,提问作者KingFate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:43:27