mysql 为什么使用ONLY_FULL_GROUP_BY

325 阅读2分钟

mysql的ONLY_FULL_GROUP_BY的意义是什么, ONLY_FULL_GROUP_BY 是 MySQL 中的一种 SQL 模式,它确保在执行 GROUP BY 查询时,查询的结果更加明确和符合 SQL 标准。具体来说,当启用了 ONLY_FULL_GROUP_BY 模式后,所有在 SELECTHAVINGORDER BY 中出现的字段,如果不是聚合函数的一部分,那么它们必须出现在 GROUP BY 子句中。

简单来说,这个模式的目的是避免查询结果模棱两可的情况,确保每个非聚合的字段都明确地按照 GROUP BY 进行分组。

1.具体示例

假设有一张包含员工信息的表 employees,结构如下:

idnamedepartmentsalary
1AliceIT5000
2BobHR4500
3CharlieIT6000
4DavidHR5500

现在你想按部门(department)进行分组,并计算每个部门的平均工资。

在没有 ONLY_FULL_GROUP_BY 模式下,你可以写这样的 SQL 查询:

SELECT department, name, AVG(salary)
FROM employees
GROUP BY department;

结果:

departmentnameAVG(salary)
ITAlice5500
HRBob5000

这看起来好像是对的,但其实这里有问题。虽然按部门分组了,但返回的 name 是分组中任意的一个值(例如 IT 部门返回的是 Alice,而不是 Charlie),这可能导致数据不准确。

使用 ONLY_FULL_GROUP_BY 模式

如果开启了 ONLY_FULL_GROUP_BY 模式,上面的查询会抛出错误,因为 name 字段既不在 GROUP BY 子句中,也不是聚合函数的一部分。为了修复这个问题,你可以重写查询,比如这样:

SELECT department, AVG(salary)
FROM employees
GROUP BY department;

结果:

departmentAVG(salary)
IT5500
HR5000

这样,查询结果更加明确且符合逻辑。ONLY_FULL_GROUP_BY 模式的目的是确保你不会无意中得到模糊或错误的数据。

2.启用或禁用 ONLY_FULL_GROUP_BY?

在 MySQL 中,默认情况下 ONLY_FULL_GROUP_BY 是启用的,可以通过检查 @@sql_mode 系统变量来确认这一点:

SELECT @@sql_mode;

如果 ONLY_FULL_GROUP_BY 已经被启用,并且你想要暂时禁用它(尽管这不是一个推荐的长期解决方案),你可以通过以下命令在会话级禁用它:

SET SESSION sql_mode=(SELECTREPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

或者,你也可以在 MySQL 配置文件(my.cnf 或 my.ini)中修改 sql_mode 设置来全局禁用它。

3.总结

--

虽然禁用 ONLY_FULL_GROUP_BY 可能会方便一些查询的编写,但长远来看,遵循这个规则对于保持数据查询的准确性和一致性至关重要。写 SQL 查询时,始终应确保遵循 ONLY_FULL_GROUP_BY 的原则,以避免潜在的数据解释错误。