MySQL 5.7中SET GLOBAL sql_mode失效及GROUP BY查询报错求助
MySQL 5.7.40 相关问题解决方案
1. SET GLOBAL sql_mode失效的原因及恢复方法
- 先确认全局配置是否真的修改:执行
SELECT @@GLOBAL.sql_mode;,如果结果已无ONLY_FULL_GROUP_BY,说明全局设置生效,但当前会话的sql_mode还是旧值,需重新连接MySQL会话(退出客户端再登录),或执行会话级设置:SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); - 若全局配置未变化,检查执行命令时是否遗漏
GLOBAL关键字,或当前用户是否拥有SUPER权限(BlueHost VPS用户需确认权限) - 重启mysqld后全局设置丢失,说明配置未写入持久化文件,需找到正确的配置文件添加sql_mode(参考第二个问题的排查)
- 排查额外配置文件:BlueHost VPS可能存在
/etc/my.cnf.d/、/var/lib/mysql/my.cnf这类子目录/文件,它们可能覆盖主my.cnf的设置,检查这些文件中是否有sql_mode配置
2. my.cnf中无sql_mode配置的原因
- MySQL 5.7默认启用包含
ONLY_FULL_GROUP_BY的sql_mode,默认配置文件无需显式写入该参数,启动时自动加载默认值 - BlueHost VPS可能采用配置拆分策略,sql_mode配置可能放在
/etc/my.cnf.d/下的.cnf文件中,或通过cPanel等控制面板的MySQL配置界面管理,而非直接写在主my.cnf里 - 部分场景下,sql_mode通过mysqld的启动命令行参数指定,而非配置文件,可执行
ps aux | grep mysqld查看启动参数中是否包含--sql-mode
3. 修改查询语句规避sql_mode限制
报错核心是ORDER BY中的s.EventDate未在GROUP BY中,也未做聚合处理,MySQL无法确定用分组内的哪个值排序。以下是基于业务需求的修改方案:
修改后查询语句(以取分组内最近活动日期排序为例)
SELECT g.GroupID, g.GroupName, count(s.EventDate) AS Total, MAX(s.EventDate) AS LatestEventDate -- 新增聚合字段用于排序 FROM Groups g LEFT JOIN Schedule s ON g.GroupID = s.GroupID JOIN Settings se ON g.GroupID = se.GroupID WHERE g.OrganizationID = 479 AND g.IsActive = 1 AND IFNULL(g.IsDeleted, 0) = 0 AND IFNULL(g.IsHidden, 0) = 0 AND se.SettingName = 'HideGroupNoGames' AND (s.EventDate > DATE_ADD(NOW(), INTERVAL 0 HOUR) OR g.CreateDate > DATE_ADD(DATE_ADD(NOW(), INTERVAL -1 DAY), INTERVAL 0 HOUR) OR se.SettingValue = 'False') GROUP BY g.GroupID, g.GroupName ORDER BY LatestEventDate, g.GroupName -- 使用聚合后的字段排序
补充说明
- 若业务需要取最早活动日期,将
MAX(s.EventDate)替换为MIN(s.EventDate)即可 - 原查询中
LEFT JOIN Schedule因WHERE条件里的s.EventDate > ...会自动转为INNER JOIN(除非s.EventDate为NULL时触发OR的其他条件),如需保留真正的LEFT JOIN效果,需将s.EventDate的条件移到ON子句中
内容的提问来源于stack exchange,提问作者HerrimanCoder
相关产品推荐
相关产品推荐

