mysql-sql_mode参数类型
你提供的 sql_mode
设置如下:
STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
这是一个常见的 MySQL 配置,去掉了 ONLY_FULL_GROUP_BY
,因此你的查询应该可以正常运行。以下是关于这些模式的详细解释以及如何确保它们生效的方法:
1. 当前 sql_mode
的含义
-
STRICT_TRANS_TABLES
启用严格模式,对事务性存储引擎(如 InnoDB)进行严格的 SQL 检查。如果数据插入或更新违反约束(如超出列长度),MySQL 将报错而不是尝试调整数据。 -
NO_ZERO_IN_DATE
禁止日期字段中出现零值部分(例如2023-00-12
或2023-12-00
)。 -
NO_ZERO_DATE
禁止使用全零日期(例如0000-00-00
)。 -
ERROR_FOR_DIVISION_BY_ZERO
在除以零时生成错误或警告。如果没有启用严格模式,这只会生成警告。 -
NO_ENGINE_SUBSTITUTION
如果指定的存储引擎不可用,则会抛出错误,而不是自动替换为默认存储引擎。 -
**ONLY_FULL_GROUP_BY **
所有非聚合列必须出现在 GROUP BY 子句中。
或者,这些列必须通过聚合函数(如 COUNT()、SUM() 等)进行处理。
注意:这个配置中
ONLY_FULL_GROUP_BY
,因此GROUP BY
查询强制要求所有非聚合列都出现在GROUP BY
子句中。
如果你的查询不符合上述规则,就会触发错误,例如:
[Err] 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.id' which is not functionally dependent on columns in GROUP BY clause.
解决方法
方法 1:移除 ONLY_FULL_GROUP_BY
2. 确保设置生效
(1) 查看当前会话的 sql_mode
在当前会话中运行以下命令,确认 sql_mode
是否已更新:
SELECT @@sql_mode;
输出应为:
STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
如果输出中仍然包含 ONLY_FULL_GROUP_BY
,说明当前会话的设置未生效。
(2) 更新当前会话的 sql_mode
如果你已经设置了全局的 sql_mode
,但当前会话未更新,可以手动设置当前会话的 sql_mode
:
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
(3) 验证全局设置
如果你想确认全局的 sql_mode
是否已正确设置,可以运行以下命令:
SELECT @@global.sql_mode;
输出也应该是:
STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
3. 测试查询
现在你可以重新运行你的查询:
SELECT *
FROM test
GROUP BY c;
由于 ONLY_FULL_GROUP_BY
已被移除,查询应该可以正常执行。不过需要注意的是,直接使用 SELECT *
和 GROUP BY
可能会导致结果不符合预期,因为未在 GROUP BY
中列出的列可能会返回任意值。
4. 推荐优化查询
为了避免潜在的问题,建议明确列出需要的列,并合理使用聚合函数。例如:
SELECT c, COUNT(*) AS count
FROM test
GROUP BY c;
或者使用 ANY_VALUE()
函数来处理未分组的列:
SELECT ANY_VALUE(id), c
FROM test
GROUP BY c;
5. 总结
- 确保当前会话的
sql_mode
已更新为:STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
- 如果需要永久生效,修改 MySQL 配置文件并重启服务。
- 优化查询语句,避免直接使用
SELECT *
和不明确的GROUP BY
。
如果仍有问题,请随时告诉我!