文章目录
- 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 查询。
