MySQL 如何在MySQL中禁用ONLY_FULL_GROUP_BY?
阅读更多:MySQL 教程
简介
MySQL在实现GROUP BY操作时,默认情况下启用ONLY_FULL_GROUP_BY模式,它要求GROUP BY子句中必须包含SELECT语句中所有的非聚合列或字面常量。否则,MySQL将抛出错误,表明GROUP BY子句不正确。该模式的主要目的是强制要求开发者使用正确的GROUP BY子句,从而避免不易排查的错误和结果不一致的风险。
然而,对于某些具体的场景,我们可能需要禁用ONLY_FULL_GROUP_BY模式,以支持一些灵活的查询,并提高开发效率。本文将介绍如何在MySQL中禁用ONLY_FULL_GROUP_BY模式。
操作方法
方法一:修改MySQL配置文件
- 打开MySQL配置文件。
这里以Ubuntu16.04下的MySQL为例,其配置文件路径为/etc/mysql/mysql.conf.d/mysqld.cnf。
-
找到[mysqld]节点,修改其中的sql_mode配置项。
在sql_mode中,添加或删除ONLY_FULL_GROUP_BY标记,以禁用或启用该模式。
例如,sql_mode = “STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”,其中并没有ONLY_FULL_GROUP_BY标记。如果需要禁用ONLY_FULL_GROUP_BY模式,仅需修改成sql_mode = “STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER”即可。
-
重启MySQL服务使修改生效。
$ sudo systemctl restart mysql
方法二:使用SET语句动态修改
-
连接到MySQL客户端,并运行以下命令,查看当前的sql_mode配置项。
SELECT @@GLOBAL.sql_mode;
- 根据需要新增或删除ONLY_FULL_GROUP_BY选项。例如,如果当前配置项为:
STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
我们需要禁用ONLY_FULL_GROUP_BY模式,则运行以下语句:
SET @@GLOBAL.sql_mode=(SELECT REPLACE(@@GLOBAL.sql_mode,'ONLY_FULL_GROUP_BY',''));
- 再次运行步骤1中的查询,验证修改是否生效。
案例说明
下面我们以一个具体的案例来说明如何通过禁用ONLY_FULL_GROUP_BY模式,解决开发中的问题。
假设我们有一个订单表t_order,其中包含以下字段:
字段 | 类型 | 说明 |
---|---|---|
id | INT | 订单编号 |
user_id | INT | 用户编号 |
amount | DECIMAL | 订单金额 |
create_time | DATETIME | 创建时间 |
现在需要查询最近30天中,每个用户的累计订单金额,我们可以使用以下SQL语句:
SELECT user_id,SUM(amount) FROM t_order WHERE create_time >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) GROUP BY user_id;
如果ONLY_FULL_GROUP_BY模式启用,该查询将不能通过,MySQL会抛出以下错误:
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.t_order.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
这是由于GROUP BY子句中没有包含SELECT语句中的id字段,而此时ONLY_FULL_GROUP_BY模式要求必须包含所有非聚合列或字面常量。我们可以通过禁用ONLY_FULL_GROUP_BY模式,使查询通过,并得到预期结果。
结论
以上就是在MySQL中禁用ONLY_FULL_GROUP_BY模式的两种方法以及一个案例说明。需要注意的是,禁用ONLY_FULL_GROUP_BY模式可能会导致某些潜在的问题,建议仅在确实需要时使用,并在使用时充分考虑查询语句的正确性和安全性。
在修改MySQL配置文件时,需谨慎操作,确保修改正确且不会影响其他相关配置项。同样,在使用SET语句动态修改时,应注意线程安全和权限控制,以避免对其他会话产生影响。
总之,正确地理解和应用ONLY_FULL_GROUP_BY模式,可以帮助我们编写更加规范和安全的SQL语句,提高程序稳健性和健壮性。