mysql高版本 sql_mode = only_full_group_by的解决办法
封面图
•
2026-01-09
•
MySQL
252
0
0
0
在 MySQL 5.7 及以上版本中,默认启用了 `sql_mode = ONLY_FULL_GROUP_BY`,这会使得 **GROUP BY** 查询必须满足“所有选择的列都必须是聚合函数或出现在 GROUP BY 子句中”的规则。如果不符合这个规则,MySQL 会报错: ``` ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ... ``` --- ## 🚫 问题示例 ```sql SELECT name, age FROM users GROUP BY name; ``` 上面的 SQL 会报错,因为 `age` 没有被聚合,也没有出现在 `GROUP BY` 中。 --- ## ✅ 解决办法 ### 方法一:修改 SQL 语句(推荐) 按照 `ONLY_FULL_GROUP_BY` 的要求来写 SQL,确保每个非聚合字段都在 `GROUP BY` 子句中,或者使用聚合函数(如 `MAX`, `MIN`, `AVG`, `COUNT` 等)。 #### 正确写法示例: ```sql -- 如果你想获取每个 name 的最大 age: SELECT name, MAX(age) AS max_age FROM users GROUP BY name; -- 或者如果你想获取每个 name 的任意一个 age(不推荐,可能不一致): SELECT name, ANY_VALUE(age) FROM users GROUP BY name; ``` > `ANY_VALUE()` 是 MySQL 提供的一个函数,用于在 `ONLY_FULL_GROUP_BY` 模式下允许非聚合字段存在。 --- ### 方法二:修改 `sql_mode`(不推荐,仅用于测试环境) 如果你不想改 SQL,可以临时或永久关闭 `ONLY_FULL_GROUP_BY` 模式。 #### 1. 查看当前 sql_mode ```sql SHOW VARIABLES LIKE 'sql_mode'; ``` #### 2. 临时修改(重启后失效) ```sql SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; ``` > 注意:去掉 `ONLY_FULL_GROUP_BY`。 #### 3. 永久修改(需要编辑配置文件) 编辑 MySQL 配置文件(通常是 `/etc/my.cnf` 或 `/etc/mysql/my.cnf`),在 `[mysqld]` 下添加或修改: ```ini [mysqld] sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION ``` 然后重启 MySQL 服务: ```bash sudo systemctl restart mysql ``` --- ## 🔍 建议 - **不要轻易关闭 `ONLY_FULL_GROUP_BY`**,因为它有助于防止错误的查询逻辑。 - 尽量使用正确的 SQL 写法,确保数据一致性。 - 如果你使用的是 ORM(如 Django、Hibernate 等),注意其生成的 SQL 是否符合 `ONLY_FULL_GROUP_BY` 的规则。 --- ## 🧠 小贴士 你可以用 `ANY_VALUE()` 来绕过这个限制,但要注意它不会保证返回值的唯一性。例如: ```sql SELECT name, ANY_VALUE(age) FROM users GROUP BY name; ``` 这可能会返回任意一条记录的 `age`,不一定是你期望的那个。 --- 如果你能提供具体的 SQL 语句,我可以帮你修改成符合 `ONLY_FULL_GROUP_BY` 的方式。
上一篇:
MySQL日期时间操作函数
下一篇:
mysql有哪些存储引擎,分别有什么优点
标题录入,一次不能超过6条
留言
评论