关于MySQL OrderBy报错Expression #1 of ORDER BY

在MySQL5.7及更高版本中,由于ONLY_FULL_GROUP_BY模式默认开启,执行带有ORDER BY的查询可能导致错误。解决办法是在非聚合列上使用ANY_VALUE()函数。这允许在GROUP BY查询中包含非聚合列,避免了ONLY_FULL_GROUP_BY模式引发的问题。例如:...(此处省略具体SQL查询示例)

MySQL5.7之后sql_mode中ONLY_FULL_GROUP_BY模式默认设置为打开状态。
在所有非聚合列(也就是表中直接取的数据)上加any_value ()包裹

**注意:order by中使用的列也要包裹**

ANY_VALUE()函数对于启用了ONLY_FULL_GROUP_BY模式,使用GROUP BY进行查询时很有用;该函数用于抑制启用ONLY_FULL_GROUP_BY模式时导致的值拒绝;
例子:

SELECT
	any_value ( a.id ) AS id,
	a.footprint_id AS footprintId,
	any_value ( a.footprint_type ) AS footprintType,
	any_value ( a.user_id ) AS userId 
FROM
	info_footprint a 
WHERE
	a.footprint_type = 3 
	AND a.user_id = 1 
	AND a.del_flag = '0' 
GROUP BY
	footprint_id 
ORDER BY
	any_value(a.id) DESC 
	LIMIT 10;
<think>我们正在解决MySQL错误1055:Expression#1ofORDERBYclauseisnotinGROUPBYclause...根据引用内容,该错误通常与sql_mode中的only_full_group_by设置有关。此模式要求GROUPBY子句必须包含所有非聚合列,否则会报错。解决方案主要围绕修改sql_mode,去除only_full_group_by选项。参考多个引用,常见解决方法如下:1.临时修改当前会话的sql_mode(引用[2][5])2.永久修改MySQL配置文件(引用[3][4])3.升级Navicat(引用[3]提到可能是低版本Navicat的问题,但根本原因还是sql_mode)步骤详解:方法1:临时修改(会话级)在MySQL客户端执行:```sqlSETSESSIONsql_mode=&#39;STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION&#39;;```或者(根据引用[5]):```sqlSETsql_mode=&#39;&#39;;SETsql_mode=&#39;NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES&#39;;```注意:临时修改只在当前会话有效。方法2:永久修改(需修改配置文件)步骤:1.找到MySQL配置文件my.cnf(Linux)或my.ini(Windows)。2.在[mysqld]部分添加或修改:```sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION```3.重启MySQL服务。方法3:检查Navicat版本(如果使用Navicat)升级到最新版本可能避免此问题(引用[3]),但根本解决还是需要修改sql_mode。注意:去除only_full_group_by可能会影响SQL的严谨性,因为MySQL将允许在GROUPBY子句中不列出所有非聚合列。请根据业务需求权衡。引用中提供了多种设置,建议使用:`STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION`这个设置保留了其他严格模式,仅去掉了only_full_group_by。另外,引用[5]提到先设置为空再设置其他模式,但通常直接设置整个字符串即可。如果不想修改全局设置,也可以考虑修改SQL语句,确保GROUPBY子句包含所有SELECT中非聚合的列,或者使用ANY_VALUE()函数(MySQL5.7以上)引用非聚合列,例如:```sqlSELECTname,ANY_VALUE(address),MAX(age)FROMtGROUPBYname;```但根据问题描述,错误中提到了ORDERBY子句,所以也可能是ORDERBY子句中的列没有在GROUPBY中出现。因此,另一种解决方案是调整SQL语句,使ORDERBY中的列包含在GROUPBY中或使用聚合函数。总结解决方案:1.修改sql_mode(临时或永久)去除only_full_group_by(最常用)。2.调整SQL语句,使其符合only_full_group_by规则。3.升级客户端工具(如Navicat)。根据引用[1][2][3][4][5],主要推荐修改sql_mode。因此,我们给出步骤:步骤1:查看当前sql_mode```sqlSELECT@@sql_mode;```步骤2:去除其中的ONLY_FULL_GROUP_BY(可以通过重新设置sql_mode实现)步骤3:如果选择永久修改,则修改配置文件并重启。示例(临时修改):```sql--假设当前sql_mode包含ONLY_FULL_GROUP_BYSETSESSIONsql_mode=(SELECTREPLACE(@@sql_mode,&#39;ONLY_FULL_GROUP_BY&#39;,&#39;&#39;));```或者直接设置成目标模式(避免替换不干净):```sqlSETSESSIONsql_mode=&#39;STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION&#39;;```注意:不同的MySQL版本默认的sql_mode可能不同,建议先查看当前的sql_mode,然后去掉ONLY_FULL_GROUP_BY后,再设置回去。例如,如果当前sql_mode是:`ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION`则去除ONLY_FULL_GROUP_BY后为:`STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION`这样修改可以保留其他模式。永久修改同样,在配置文件中设置去除ONLY_FULL_GROUP_BY后的字符串。根据引用[5],还有一种做法是直接设置为空,但这样会关闭所有严格模式,不推荐。因此,推荐做法是去除ONLY_FULL_GROUP_BY,但保留其他严格模式。最后,生成相关问题:</think>### MySQL错误1055解决方案:ORDER BY子句问题 MySQL错误`Expression #1 of ORDER BY clause is not in GROUP BY clause`是由于`sql_mode`中的`ONLY_FULL_GROUP_BY`模式导致的。该模式要求`GROUP BY`子句必须包含所有`SELECT`或`ORDER BY`中的非聚合列。以下是详细解决方案: --- ### **解决方法** #### 方法1:修改当前会话的sql_mode(临时生效) ```sql -- 查看当前sql_mode SELECT @@sql_mode; -- 移除ONLY_FULL_GROUP_BY(示例保留其他严格模式) SET SESSION sql_mode = &#39;STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION&#39;; ``` #### 方法2:永久修改配置文件(需重启MySQL1. **找到配置文件**: - Linux:`/etc/my.cnf` 或 `/etc/mysql/my.cnf` - Windows:`my.ini`(通常在MySQL安装目录) 2. **在`[mysqld]`段落下添加**: ```ini sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION ``` 3. **重启MySQL服务**: ```bash # Linux sudo systemctl restart mysqld # Windows(服务管理器重启MySQL服务) ``` #### 方法3:升级Navicat(工具兼容性问题) 如果使用低版本Navicat连接MySQL 5.7+,升级Navicat到最新版可能解决[^3]。 #### 方法4:修改SQL语句(推荐) 保持`ONLY_FULL_GROUP_BY`模式,但调整SQL语法: ```sql -- 原始错误语句 SELECT department, name, AVG(salary) FROM employees GROUP BY department ORDER BY name; -- name不在GROUP BY中 -- 修正方案1:将name加入GROUP BY SELECT department, name, AVG(salary) FROM employees GROUP BY department, name -- 同时分组 ORDER BY name; -- 修正方案2:使用ANY_VALUE()(MySQL 5.7+) SELECT department, ANY_VALUE(name), AVG(salary) FROM employees GROUP BY department ORDER BY ANY_VALUE(name); ``` --- ### **原因分析** - **核心问题**:MySQL 5.7+默认启用`ONLY_FULL_GROUP_BY`,要求`GROUP BY`必须包含所有非聚合列[^1][^2]。 - **常见触发场景**: - `SELECT`或`ORDER BY`包含未在`GROUP BY`中列出的非聚合列 - 使用低版本数据库客户端(如旧版Navicat)[^3] - **安全提示**:禁用`ONLY_FULL_GROUP_BY`可能降低查询严谨性,建议优先修正SQL语句[^5]。 --- ### **验证是否解决** ```sql -- 检查sql_mode是否生效 SELECT @@sql_mode; -- 确认结果中无ONLY_FULL_GROUP_BY ``` > **注意**:永久修改需重启MySQL服务,生产环境建议在低峰期操作[^4]。 --- ### 相关问题 1. `ONLY_FULL_GROUP_BY`模式对SQL查询有何性能影响? 2. 如何在MySQL 8.0中安全地修改`sql_mode`? 3. 除`ANY_VALUE()`外,还有哪些函数可处理非聚合列的分组查询? 4. 为什么MySQL 5.7+默认启用`ONLY_FULL_GROUP_BY`? 5. 如何在不修改`sql_mode`的情况下优化包含`GROUP BY`和`ORDER BY`的复杂查询? [^1]: MySQL报错1055核心原因是`sql_mode=only_full_group_by`,需移除该模式 [^2]: 通过`SET sql_mode=&#39;...&#39;`可临时解决,配置文件修改可永久生效 [^3]: 低版本Navicat连接高版本MySQL可能触发此错误,升级客户端可解 [^4]: 修改配置文件后需重启MySQL服务,生产环境需谨慎 [^5]: 优先推荐修正SQL语句而非禁用`ONLY_FULL_GROUP_BY`以保证查询严谨性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值