文章目录
- 1. 什么是聚合列?
- 2. 什么是非聚合列?
- 3. 在 `GROUP BY` 查询中的非聚合列
- 问题示例
- 解决方案
- 4. 为什么 `only_full_group_by` 要求非聚合列出现在 `GROUP BY` 中?
- 5. 如何判断一个列是聚合列还是非聚合列?
- 6. 总结
在 SQL 中, 非聚合列是指那些没有使用聚合函数(如
COUNT、
SUM、
AVG、
MAX、
MIN 等)的列。理解这个概念的关键在于区分
聚合列 和
非聚合列。
1. 什么是聚合列?
聚合列是指使用了聚合函数的列。聚合函数会对一组值进行计算,并返回一个单一的值。例如:
COUNT(*):计算行数。SUM(column):计算某列的总和。AVG(column):计算某列的平均值。MAX(column):返回某列的最大值。MIN(column):返回某列的最小值。
示例:
SELECT COUNT(*) AS total_users FROM users;
- 这里的
COUNT(*)是一个聚合列,因为它使用了聚合函数COUNT。
2. 什么是非聚合列?
非聚合列是指没有使用聚合函数的列。这些列直接来自表中的数据,而不是通过计算得到的。
示例:
SELECT name, age FROM users;
- 这里的
name和age都是非聚合列,因为它们直接来自表中的数据,没有使用任何聚合函数。
3. 在 GROUP BY 查询中的非聚合列
当使用 GROUP BY 时,查询会将数据按指定的列分组。对于非聚合列,MySQL 需要明确知道如何选择值,因为每个分组可能包含多行数据。
问题示例
假设有一个表 users,数据如下:
| id | name | age |
|---|---|---|
| 1 | Alice | 20 |
| 2 | Bob | 20 |
| 3 | Charlie | 25 |
执行以下查询:
SELECT name, age, COUNT(*) FROM users GROUP BY age;
- 这里的
age是分组列,COUNT(*)是聚合列。 - 但
name是非聚合列,它没有出现在GROUP BY子句中,也没有使用聚合函数。 - MySQL 不知道在分组后应该选择哪个
name值(因为age=20对应两个name:Alice和Bob)。
解决方案
-
将非聚合列添加到
GROUP BY子句中:SELECT name, age, COUNT(*) FROM users GROUP BY name, age;- 这样,MySQL 会按
name和age分组,确保每个分组只有一行数据。
- 这样,MySQL 会按
-
使用聚合函数处理非聚合列:
SELECT MAX(name), age, COUNT(*) FROM users GROUP BY age;- 这里使用
MAX(name),表示选择每个分组中name的最大值。
- 这里使用
4. 为什么 only_full_group_by 要求非聚合列出现在 GROUP BY 中?
only_full_group_by 模式的目的是确保查询结果的明确性。如果没有这个限制,MySQL 可能会随机选择一个值作为非聚合列的结果,导致查询结果不可预测。
示例:
SELECT name, age, COUNT(*) FROM users GROUP BY age;
- 如果
age=20对应两个name(Alice和Bob),MySQL 可能随机返回Alice或Bob,这会导致结果不一致。
通过启用 only_full_group_by,MySQL 会强制要求所有非聚合列都出现在 GROUP BY 子句中,从而避免这种不确定性。
5. 如何判断一个列是聚合列还是非聚合列?
- 聚合列:使用了聚合函数(如
COUNT、SUM、AVG、MAX、MIN等)。 - 非聚合列:直接来自表中的数据,没有使用聚合函数。
示例:
SELECT name, age, COUNT(*) AS total_users FROM users GROUP BY name, age;
name和age是非聚合列。COUNT(*)是聚合列。
6. 总结
- 非聚合列是指没有使用聚合函数的列,直接来自表中的数据。
- 在
GROUP BY查询中,所有非聚合列必须出现在GROUP BY子句中,或者使用聚合函数处理。 only_full_group_by模式的作用是确保查询结果的明确性,避免不明确的值。
通过理解聚合列和非聚合列的区别,可以更好地编写符合 only_full_group_by 要求的 SQL 查询。



















