(经典)使用group by出现错误.要注意什么?

本文详细解析了 SQL 中 Group By 子句的正确使用方法,包括其与聚合函数的配合使用、常见错误示例及解决方案,帮助读者理解如何有效地进行数据分组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

select * from Products group by CategoryID
我用的数据库是NorthWind

错误提示:
Msg 8120, Level 16, State 1, Line 2
Column 'Products.ProductID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

==================================================
简单来说吧。
使用group by 的时个,某个字段中相同的值将会被认为是一个,
如下表table1:
ID name
1 xiaowang
2 xiaowang
3 xx
4 bb
select name from table1 group by name
得到的结果是
xiaowang
xx
bb
也说是可以简单的认为相同情况只取一次
所以得到的表,与原来的表就存在被丢弃的现像,这样当然不能用 select * 了,
理论上这个只能与sum,count---一起用了!
也就是要读取的字段,必须也能相应的“减少”行!

==================================================
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面
所以按你上面的列子应该把你所要显示的所有列名都写到
group by后

==================================================
select item.itemnum,item.in1,item.in4,inventory.location from item,inventory
where item.itemnum=inventory.itemnum
and inventory.location='DYB'
and item.in1='D/MTD/MRM'
GROUP BY ITEM.ITEMNUM
提示错误是NOT A GROUP BY EXPRESSION
那位高人能指点一下是我是那里出错了,还有GROUP BY的用法
谢谢了哈!

==================================================

GROUP BY 是分组查询, 一般 GROUP BY 是和 聚合函数配合使用,你可以想想

你用了GROUP BY 按 ITEM.ITEMNUM 这个字段分组,那其他字段内容不同,变成一对多又改如何显示呢,比如下面所示

A B
1 abc
1 bcd
1 asdfg

select A,B from table group by A
你说这样查出来是什么结果,

A B
    abc
1 bcd
    asdfg

右边3条如何变成一条,所以需要用到聚合函数,比如

select A,count(B) 数量 from table group by A
这样的结果就是
A 数量
1 3

group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面

==================================================
总结      

        在select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。group by 子句可以将查询结果分组,并返回行的汇总信息Oracle 按照group by 子句中指定的表达式的值分组查询结果。

        在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数

select max(sal),job emp group by job;
(注意max(sal),job的job并非一定要出现,但有意义)

     
  查询语句的select 和group by ,having 子句是聚组函数唯一出现的地方,在where 子句中不能使用聚组函数。

select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;

        当在gropu by 子句中使用having 子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having 与where 子句类似,均用于设置限定条件


       where 子句的作用
是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。 
        having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。

      
查询每个部门的每种职位的雇员数
select deptno,job,count(*) from emp group by deptno,job;

       group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面,并且若有order by子句,则order by后面的子句后面的列也必须出现在 group by 后面。
select  ... from ... where ... group by ... having ... order by ...  
select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;

=================================================

<think>好的,我现在要解决用户提到的SQL错误:[Err] 1055,关于ORDER BY子句中的表达式不在GROUP BY子句中。首先,我需要理解这个错误的原因。根据引用内容,错误是由于MySQLsql_mode设置为only_full_group_by导致的。这个模式要求SELECT、HAVING或ORDER BY列表中的非聚合列必须出现在GROUP BY子句中,或者这些列在功能上依赖于GROUP BY的列。如果用户的查询中ORDER BY的列不在GROUP BY里,并且不是聚合函数的结果,就会触发这个错误。 接下来,我需要考虑解决方法。根据引用中的信息,有两种主要方法:修改SQL查询或调整sql_mode设置。用户可能需要保持sql_mode严格,所以修改查询可能更合适。例如,确保ORDER BY中的列包含在GROUP BY里,或者使用聚合函数处理这些列。例如,如果用户按某个字段排序但未在GROUP BY中列出,可能需要添加该字段到GROUP BY,或者使用MAX()等函数。 另一个方法是修改sql_mode,移除only_full_group_by选项。但这样做可能会降低数据一致性,需谨慎。引用[4]和[5]提到如何查看和修改sql_mode,包括临时和永久的方法。用户可能需要指导如何执行这些步骤,比如编辑MySQL配置文件或在会话中设置。 还需要考虑用户的具体情况。比如他们是否在开发环境,是否可以安全地修改配置,或者是否需要保持与其他数据库的兼容性。此外,可能还需要解释为什么这个错误会发生,帮助用户理解背后的SQL标准,以便未来避免类似问题。 最后,我需要总结这些方法,并生成相关问题,帮助用户深入理解。例如,如何检查当前的sql_mode,或者GROUP BY的其他使用注意事项。</think>### 解决 SQL 中 "Expression not in GROUP BY clause" 错误的方法 #### 错误原因分析 当 MySQL 的 `sql_mode` 包含 `only_full_group_by` 时,要求 `SELECT`、`HAVING` 或 `ORDER BY` 中的非聚合列必须满足以下条件之一: 1. 出现在 `GROUP BY` 子句中; 2. 在功能上依赖于 `GROUP BY` 的列(例如主键或唯一索引)。 若违反此规则,则会触发错误:[Err] 1055[^1][^2][^3]。 --- #### 解决方法 ##### 方法 1:修改 SQL 查询 **适用场景**:需要严格遵循 SQL 标准,保证查询的严谨性。 1. **将 `ORDER BY` 的列添加到 `GROUP BY`** 例如: ```sql SELECT department, COUNT(*) FROM employees GROUP BY department ORDER BY department; -- 确保 ORDER BY 的列在 GROUP BY 中 ``` 2. **使用聚合函数处理非聚合列** 例如: ```sql SELECT department, MAX(salary) FROM employees GROUP BY department ORDER BY MAX(salary); -- 对排序列使用聚合函数 ``` ##### 方法 2:调整 MySQL 的 `sql_mode` **适用场景**:临时解决兼容性问题(需评估数据一致性风险)。 1. **查看当前 `sql_mode`** ```sql SELECT @@sql_mode; ``` 输出可能包含 `ONLY_FULL_GROUP_BY`[^4][^5]。 2. **临时修改(仅当前会话生效)** ```sql SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; ``` 3. **永久修改(需重启 MySQL)** 在 MySQL 配置文件(如 `my.cnf` 或 `my.ini`)中添加: ```ini [mysqld] sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION ``` --- #### 注意事项 - **优先修改查询**:`only_full_group_by` 可避免未定义的分组行为,建议优先优化 SQL 逻辑[^1][^4]。 - **兼容性影响**:移除 `only_full_group_by` 可能导致其他数据库系统不兼容。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值