错误仅与相关
我升级了我的系统,并安装了MySql 5.7.9,并使用了我正在开发的Web应用程序。 我有一个动态创建的查询,并在旧版本的MySql中运行时,它工作正常。 自升级到5.7我得到这个错误:
SELECT列表的表达式#1不在GROUP BY子句中,并且包含非聚集列'support_desk.mod_users_groups.group_id',它在功能上不依赖于GROUP BY子句中的列; 这与sql_mode = only_full_group_by不兼容
请注意关于服务器SQL模式主题的Mysql 5.7手册页。
这是给我带来麻烦的查询:
SELECT mod_users_groups.group_id AS 'value',
group_name AS 'text'
FROM mod_users_groups
LEFT JOIN mod_users_data ON mod_users_groups.group_id = mod_users_data.group_id
WHERE mod_users_groups.active = 1
AND mod_users_groups.department_id = 1
AND mod_users_groups.manage_work_orders = 1
AND group_name != 'root'
AND group_name != 'superuser'
GROUP BY group_name
HAVING COUNT(`user_id`) > 0
ORDER BY group_name
我在这个问题上做了一些搜索,但我不明白only_full_group_by
足以找出我需要做什么来修复查询。 我可以关闭only_full_group_by
选项,还是还有其他我需要做的事情?
如果您需要更多信息,请与我们联系。
我只是将group_id
添加到GROUP BY
。
当SELECT
不属于GROUP BY
一部分的列时,组中的该列可能有多个值,但结果中只有空间可存储单个值。 因此,通常需要知道如何将这些多个值合并为一个值。 通常,这是用像COUNT()
, SUM()
, MAX()
等集合函数完成的......我通常说是因为大多数其他流行的数据库系统坚持这样做。 但是,在5.7版以前的MySQL中,默认行为更为宽容,因为它不会抱怨,然后随意选择任何值! 它还有一个ANY_VALUE()
函数,如果你真的需要和以前一样的行为,可以作为这个问题的另一个解决方案。 这种灵活性的代价是非确定性的,所以我不会推荐它,除非你有很好的理由需要它。 由于很好的原因,MySQL现在默认打开了only_full_group_by
设置,因此最好习惯它并使查询符合它。
那么为什么我上面的简单答案? 我做了一些假设:
1) group_id
是唯一的。 看起来合理,毕竟这是'身份证'。
2) group_name
也是唯一的。 这可能不是一个合理的假设。 如果情况并非如此,并且您有一些重复的group_names
,然后按照我的建议将group_id
添加到GROUP BY
,则可能会发现现在您获得的结果比以前更多,因为具有相同名称的组现在将具有单独的行结果。 对我来说,这会比隐藏这些重复的组更好,因为数据库已经悄悄地选择了一个值!
当涉及多个表时,使用表名或别名限定所有列也是一个好习惯......
SELECT
g.group_id AS 'value',
g.group_name AS 'text'
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id
WHERE g.active = 1
AND g.department_id = 1
AND g.manage_work_orders = 1
AND g.group_name != 'root'
AND g.group_name != 'superuser'
GROUP BY
g.group_name,
g.group_id
HAVING COUNT(d.user_id) > 0
ORDER BY g.group_name
您可以尝试通过执行以下操作来禁用only_full_group_by
设置:
mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
您可以按照其他答案中的说明关闭警告消息,或者您可以了解发生的情况并对其进行修复。
从MySQL 5.7.5开始,默认的SQL模式包括ONLY_FULL_GROUP_BY,这意味着当您对行进行分组然后从这些组中选择某些内容时,您需要明确说明应该从哪个行进行选择。
Mysql需要知道您要查找的组中的哪一行,这给了您两个选项
group by rect.color, rect.value
将您想要的列添加到组语句group by rect.color, rect.value
这可以在某些情况下是您想要的,否则将返回具有您可能不想要的相同颜色的重复结果 AVG()
MIN()
MAX()
完整列表 ANY_VALUE()
。 DOC 下一篇: What is the MySQL equivalent of PostgreSQL's EXPLAIN ANALYZE