SQL中聚合列 vs 非聚合列

在 SQL 中,非聚合列指的是在查询中没有使用聚合函数的列。聚合函数是对一组值进行计算并返回单个值的函数,例如 SUM()、COUNT()、AVG()、MIN()、MAX() 等。

一、聚合列 vs 非聚合列

1. 聚合列: 

使用了聚合函数的列。例如:

   SELECT SUM(sales) AS total_sales FROM orders;

- SUM(sales) 是聚合列,因为它使用了聚合函数 SUM()。

2. 非聚合列: 

没有使用聚合函数的列。例如:

   SELECT customer_id, sales FROM orders;

- customer_id 和 sales 是非聚合列,因为它们没有使用聚合函数。

-

二、非聚合列导致的问题

在 SQL 中,如果查询中使用了聚合函数(如 SUM()、COUNT() 等),并且同时存在非聚合列,数据库引擎需要明确如何处理这些非聚合列。

  1. 例如:

SELECT

  customer_id,

  SUM(sales) AS total_sales

FROM orders;

- SUM(sales) 是聚合列,返回一个汇总值。

- customer_id 是非聚合列,每一行都有一个不同的值。

分析:在这种情况下,数据库引擎不知道如何将 customer_id 与 SUM(sales) 的结果对应起来,因此会抛出错误。

2.  解决方法

(1)使用 GROUP BY 

将非聚合列添加到 GROUP BY 子句中,明确分组依据:

   SELECT

     customer_id,

     SUM(sales) AS total_sales

   FROM orders

   GROUP BY customer_id;

- 这里 customer_id 是分组依据,每个 customer_id 对应一个 SUM(sales) 的结果。

(2)移除非聚合列 

如果不需要非聚合列,可以直接移除:

   SELECT

     SUM(sales) AS total_sales

   FROM orders;

(3)使用聚合函数处理非聚合列 

   如果需要对非聚合列进行聚合操作,可以使用聚合函数:

   SELECT

     MAX(customer_id) AS last_customer,

     SUM(sales) AS total_sales

   FROM orders;

解释:因为都只有一个值,所有可以对的上。

-

三、总结

- 非聚合列:没有使用聚合函数的列。

- 在包含聚合函数的查询中,非聚合列必须出现在 GROUP BY 子句中,或者使用聚合函数进行处理。

- 如果不处理非聚合列,SQL 查询会抛出错误(如 MySQL 的错误 1140)。

### MySQL聚合非聚合列的区别及使用场景 #### 一、定义区别 - **聚合**是指经过某种聚合操作处理后的,通常由聚合函数生成的结果。常见的聚合函数有 `COUNT()`、`SUM()`、`AVG()`、`MAX()` 和 `MIN()` 等[^3]。这些函数会对一组或多组数据进行统计运算并返回单一值。 - **非聚合列**则是指未被任何聚合函数作用过的原始表字段。它们表示的是数据库中实际存储的数据,在查询过程中如果没有应用聚合函数,则保持原样输出。 #### 二、语法行为差异 当 SQL 查询涉及 `GROUP BY` 子句时: 1. 如果启用了 `ONLY_FULL_GROUP_BY` 模式 (MySQL 5.7.5 及更高版本默认启用)[^2],那么 SELECT 表中的每一项要么是分组依据的 (`group column`),要么是由聚合函数产生的结果; 2. 若试图选取不属于上述两类的其他普通(即非聚合列),将会引发错误提示:“In aggregated query without GROUP BY, expression #X of SELECT list contains nonaggregated column...”。 不过存在例外情形——即使开启了 ONLY_FULL_GROUP_BY ,只要满足特定条件仍可访问某些类型的非聚集字段: * 当前分组键为主键(primary key) 或唯一索引(unique index),并且该索引不能为空(NULLable); * 使用 ANY_VALUE() 函数包裹待提取的目标名作为替代方案之一 [^2]. #### 三、典型应用场景对比分析 | 场景描述 | 推荐使用的类型 | 示例 | |----------|------------------------|-----------------------------------------------------------------------------------------| | 统计总数 | 聚合 | 计算某张订单详情表里所有商品数量合计:<br>`SELECT SUM(quantity) FROM order_details;` | | 平均价格评估 | 聚合 | 获取客户购买的商品均价:<br>```sql<br>SELECT AVG(price)<br>FROM products;<br>``` | | 查找最大/最小值 | 聚合 | 寻觅员工薪资最高者的信息:<br>```sql<br>SELECT MAX(salary), department_id<br>FROM employees<br>GROUP BY department_id;<br>``` | | 数据明细展示 | 非聚合列 | 展现各部门下的具体职员名单及其基本信息:<br>```sql<br>SELECT employee_name, hire_date, salary, department_id<br>FROM employees<br>ORDER BY department_id ASC;<br>``` | 值得注意的一点是在混合运用这两种不同性质的时需格外谨慎考虑逻辑关系以免造成误解或冗余计算。例如欲知各地区男性成员缴纳费用总额就不能单纯依赖 WHERE 来完成过滤工作而应借助HAVING子句配合GROUP BY共同达成目标;同样道理如果仅仅是为了得到某个固定分类下数值累加结果的话确实可以直接通过WHERE预选后再执行相应汇总即可无需额外引入复杂的层次结构[^1]。 ```python # Python伪代码演示如何模拟简单的SQL Group By操作 data = [ {"country": "US", "sex":"man","fee":10}, {"country": "CN", "sex":"woman","fee":20}, {"country": "US", "sex":"man","fee":15} ] from collections import defaultdict def group_by_and_sum(data,key_field,value_field): result=defaultdict(int) for item in data: key=item[key_field] value=item[value_field] result[key]+=value return dict(result) print(group_by_and_sum(data,"country","fee")) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值