我已经升级了我的系统,并为我正在开发的web应用程序安装了MySql 5.7.9和php。我有一个查询,是动态创建的,当运行在旧版本的MySQL它工作得很好。自从升级到5.7,我得到这个错误:

SELECT列表的表达式#1不在GROUP BY子句中,并且包含 未聚合列的support_desk.mod_users_groups。Group_id '就是 在功能上不依赖于GROUP BY子句中的列;这是 sql_mode=only_full_group_by不兼容

请注意Mysql 5.7的手册页中关于Server SQL Modes的主题。

这个问题让我很困扰:

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选项,或者还有其他需要做的事情?


当前回答

如果您在Symfony使用doctrine查询构建器时出现此错误,并且此错误是由orderBy引起的:

注意选择你想要groupBy的列,使用addGroupBy而不是groupBy:

$query = $this->createQueryBuilder('smth')->addGroupBy('smth.mycolumn');

工作在Symfony3 -

其他回答

您可以像其他答案中解释的那样关闭警告消息,或者您可以了解发生了什么并修复它。

从MySQL 5.7.5开始,默认的SQL模式只包括ONLY_FULL_GROUP_BY,这意味着当你对行进行分组,然后从组中选择一些东西时,你需要显式地说应该从哪一行进行选择。

Mysql需要知道您要查找组中的哪一行,这为您提供了两个选项

你也可以将你想要的列添加到group语句group中,通过矩形。color,矩形。value,这在某些情况下可以是你想要的,否则会返回相同颜色的重复结果,这可能不是你想要的 你也可以使用mysql的聚合函数来指示你在AVG() MIN() MAX()完整列表中的组中寻找哪一行 最后,如果您确定组内的所有结果都相同,则可以使用ANY_VALUE()。医生

可以为group_id添加唯一索引;如果您确定group_id是唯一的。

它可以在不修改查询的情况下解决您的问题。

迟来的回答,但在回答中还没有提到。也许它应该完善现有的已经很全面的答案。至少,当我不得不分割一个包含太多字段的表时,它确实解决了我的问题。

使用ANY_VALUE()引用未聚合的列。

SELECT name,           address , MAX(age) FROM t GROUP BY name; -- fails
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name; -- works

从MySQL 5.7文档:

You can achieve the same effect without disabling ONLY_FULL_GROUP_BY by using ANY_VALUE() to refer to the nonaggregated column. ... This query might be invalid with ONLY_FULL_GROUP_BY enabled because the nonaggregated address column in the select list is not named in the GROUP BY clause: SELECT name, address, MAX(age) FROM t GROUP BY name; ... If you know that, for a given data set, each name value in fact uniquely determines the address value, address is effectively functionally dependent on name. To tell MySQL to accept the query, you can use the ANY_VALUE() function: SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;

可以通过以下命令禁用only_full_group_by setting。

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 8不接受NO_AUTO_CREATE_USER,所以需要删除。

mac:

1.复制默认的my-default.cnf到/etc/my.cnf

sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf

2.使用您喜欢的编辑器更改my.cnf中的sql_mode并将其设置为此

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

3.重新启动MySQL服务器。

mysql.server restart