为什么SQL中的MAX聚合语句同样需要使用GROUP BY子句?
SQL查询要求GROUP BY的逻辑解答
核心通用规则
SQL标准对聚合查询的要求是统一的:只要SELECT子句中同时出现了聚合函数(SUM/MAX/MIN/COUNT/AVG等)和未被聚合包裹的普通列,所有未被聚合的普通列必须全部放到GROUP BY子句中。这个规则和聚合函数本身的计算逻辑无关,不管是求和的SUM还是取最大值的MAX都要遵守。
第二个查询要求GROUP BY的具体原因
你对MAX函数的认知存在小偏差:不带分组的max(FilmOscarWins)是扫描整个tblFilm表得到的全局唯一最大值,并不是直接绑定某一行的存储值。
我们可以举个实际的表数据例子:
| FilmName | FilmOscarWins |
|---|---|
| 泰坦尼克号 | 11 |
| 指环王3:王者归来 | 11 |
| 阿凡达 | 3 |
此时全局计算得到的max(FilmOscarWins)结果是11,但数据库无法判断你要把这个11和哪个FilmName做关联:是返回泰坦尼克号?还是指环王3?没有明确规则的情况下,数据库无法输出确定的结果,因此必须要求你通过GROUP BY声明分组维度:
- 如果你要查询每部电影对应的最高获奖数(如果表中每个电影只有一行记录,这个写法实际意义不大,MAX的返回值就是该行本身的获奖数),正确写法:
select max(FilmOscarWins),FilmName From tblFilm GROUP BY FilmName
- 如果你要查询获得最多奥斯卡奖的所有电影名称,不需要分组,用子查询筛选即可,参考写法:
select FilmName, FilmOscarWins From tblFilm where FilmOscarWins = (select max(FilmOscarWins) from tblFilm)
两个查询的底层逻辑一致性
你对第一个查询的理解是正确的,本质上两个查询触发GROUP BY要求的原因完全相同:
- 第一个查询中
sum(OrderSales)是聚合计算结果,数据库不知道该对应哪个OrderDates - 第二个查询中
max(FilmOscarWins)是聚合计算结果,数据库不知道该对应哪个FilmName
核心都是聚合结果和普通列没有默认的对应关系,需要你手动声明分组规则来明确匹配逻辑。
内容的提问来源于stack exchange,提问作者ah2Bwise
相关产品推荐
相关产品推荐

