Dan*_*ski 394 mysql sql group-by mysql-error-1055
我已经升级了我的系统,并为我正在处理的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不兼容
请注意有关服务器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
Run Code Online (Sandbox Code Playgroud)
我在这个问题上做了一些谷歌搜索,但我不明白only_full_group_by弄清楚我需要做些什么来修复查询.我可以关掉这个only_full_group_by选项,还是我需要做些什么呢?
如果您需要更多信息,请与我们联系.
Wei*_*uan 332
您可以尝试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';
Run Code Online (Sandbox Code Playgroud)
MySQL 8不接受,NO_AUTO_CREATE_USER因此需要删除.
dav*_*mos 323
我只想补充group_id一下GROUP BY.
当SELECT不属于GROUP BY该列的列时,组中的该列可能有多个值,但结果中只有一个值的空间.因此,通常需要告知数据库如何将这些多个值组合成一个值.通常,这与聚合函数一样做COUNT(),SUM(),MAX()等...我说一般,因为大多数其他流行的数据库系统坚持这一点.但是,在版本5.7之前的MySQL中,默认行为更宽容,因为它不会抱怨然后随意选择任何值!ANY_VALUE()如果你真的需要和以前一样的行为,它还有一个函数可以用作这个问题的另一个解决方案.这种灵活性是有代价的,因为它是非确定性的,所以除非你有充分的理由需要它,否则我不推荐它.MySQL现在only_full_group_by默认打开设置是有充分理由的,所以最好习惯它并让你的查询符合它.
那我为什么简单回答呢?我做了几个假设:
1)这group_id是独一无二的.看似合理,毕竟它是一个'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
Run Code Online (Sandbox Code Playgroud)
aze*_*ati 305
您可以按照其他答案中的说明关闭警告消息,或者您可以了解正在发生的事情并进行修复.
从MySQL 5.7.5开始,默认的SQL模式包括ONLY_FULL_GROUP_BY,这意味着当您对行进行分组然后从该组中选择一些内容时,您需要明确说明应该从哪个行进行选择.

Mysql需要知道您正在寻找的组中的哪一行,这为您提供了两个选项
group by rect.color, rect.value,这可能是您想要的,但在某些情况下会返回您可能不需要的相同颜色的重复结果AVG() MIN() MAX() 完整列表 ANY_VALUE()如果您确定组内的所有结果都相同,则可以使用.DOCAja*_*jai 166
如果您不想在当前查询中进行任何更改,请按照以下步骤操作 -
sudo vim /etc/mysql/my.cnfA以进入插入模式复制和粘贴
[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Run Code Online (Sandbox Code Playgroud)键入esc退出输入模式
:wq以保存并关闭vim.sudo service mysql restart以重新启动MySQL.Ita*_*tto 55
使用ANY_VALUE()来指代非聚集列.
来自MySQL 5.7文档:
您可以
ONLY_FULL_GROUP_BY通过使用ANY_VALUE()引用非聚合列来实现相同的效果而不禁用....
ONLY_FULL_GROUP_BY启用此查询可能无效,因为选项列表中的非聚合地址列未在GROUP BY子句中命名:Run Code Online (Sandbox Code Playgroud)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接受查询,可以使用以下
ANY_VALUE()函数:Run Code Online (Sandbox Code Playgroud)SELECT name, address, MAX(age) FROM t GROUP BY name;
Abr*_*lov 45
我会试着解释一下这个错误是什么.
从MySQL 5.7.5开始ONLY_FULL_GROUP_BY,默认情况下启用选项.
因此,根据标准SQL92和更早版本:
不允许选择列表,HAVING条件或ORDER BY列表引用非聚合列的查询,这些列既不在GROUP BY子句中命名,也不在功能上依赖于(唯一确定)GROUP BY列
所以,例如:
SELECT * FROM `users` GROUP BY `name`;
Run Code Online (Sandbox Code Playgroud)
执行上述查询后,您将收到错误消息.
#1055 - SELECT列表的表达式#1不在GROUP BY子句中,并且包含非聚合列'testsite.user.id',它在功能上不依赖于GROUP BY子句中的列; 这与sql_mode = only_full_group_by不兼容
为什么?
因为MySQL不完全理解,从分组记录中检索哪些特定值,这就是重点.
并且您将执行上面的无效查询showen.
并且您将得到上面显示的错误,因为,有3个记录具有名称John,并且它很好,但是,它们都具有不同的email字段值.
因此,MySQL根本不了解它们中的哪一个返回到结果分组记录中.
您可以通过简单地更改您的查询来解决此问题:
SELECT `name` FROM `users` GROUP BY `name`
Run Code Online (Sandbox Code Playgroud)
此外,您可能希望向SELECT部分添加更多字段,但是如果它们没有聚合,您可能无法这样做,但是您可以使用拐点(但非常不推荐):
SELECT ANY_VALUE(`id`), ANY_VALUE(`email`), `name` FROM `users` GROUP BY `name`
Run Code Online (Sandbox Code Playgroud)
现在,你可能会问,为什么使用ANY_VALUE高度不推荐?
因为MySQL并不确切知道要检索的分组记录的值,并且通过使用此函数,您要求它获取它们中的任何一个(在这种情况下,获取名称= John的第一条记录的电子邮件).
究竟我无法想出为什么你希望这种行为存在的想法.
如果你不理解我,请阅读更多关于如何在MySQL中进行分组的工作,这很简单.
到最后,这是一个更简单但有效的查询.
如果要根据可用年龄查询总用户数,可能需要记下此查询
SELECT `age`, COUNT(`age`) FROM `users` GROUP BY `age`;
Run Code Online (Sandbox Code Playgroud)
根据MySQL规则,这完全有效.
等等.
重要的是要了解问题到底是什么,然后记下解决方案.
Rya*_*yan 39
我在laravel宅基地上使用Laravel 5.3,mysql 5.7.12(我相信0.5.0)
即使在明确设置编辑/etc/mysql/my.cnf后反映:
[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Run Code Online (Sandbox Code Playgroud)
我还是收到了错误.
我不得不改变config/database.php来自true于false:
'mysql' => [
'strict' => false, //behave like 5.6
//'strict' => true //behave like 5.7
],
Run Code Online (Sandbox Code Playgroud)
进一步阅读:
https://laracasts.com/discuss/channels/servers/set-set-sql-mode-on-homestead https://mattstauffer.co/blog/strict-mode-and-other-mysql-customizations-in-laravel -5-2
Ani*_*pta 23
转到 mysql 或 phpmyadmin 并选择数据库,然后只需执行此查询即可。它对我来说工作正常。
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)
小智 18
如果您正在使用wamp 3.0.6或除稳定版2.5之外的任何高级版本,您可能会遇到此问题,首先问题是sql.你必须相应地命名字段.但还有另一种方法可以解决它.点击wamp的绿色图标.mysql-> mysql settings-> sql_mode-> none.或者从控制台,您可以更改默认值.
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';
Run Code Online (Sandbox Code Playgroud)
Jag*_*ngh 16
在文件中添加行(如下所述):/ etc/mysql/my.cnf
[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Run Code Online (Sandbox Code Playgroud)
对我来说很好.服务器版本:5.7.18-0ubuntu0.16.04.1 - (Ubuntu)
小智 9
对于mac:
1.将默认的my-default.cnf复制到/etc/my.cnf
sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
3.Restart MySQL服务器.
mysql.server restart
Run Code Online (Sandbox Code Playgroud)
这就是帮助我了解整个问题的原因:
在下面的另一个有问题查询的示例中。
有问题的:
SELECT COUNT(*) as attempts, SUM(elapsed) as elapsedtotal, userid, timestamp, questionid, answerid, SUM(correct) as correct, elapsed, ipaddress FROM `gameplay`
WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY)
AND cookieid = #
Run Code Online (Sandbox Code Playgroud)
通过将其添加到末尾来解决:
GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress
Run Code Online (Sandbox Code Playgroud)
注意:请参阅PHP中的错误消息,它告诉您问题出在哪里。
例:
MySQL查询错误1140:在没有GROUP BY的聚合查询中,SELECT列表的表达式#4包含非聚合列'db.gameplay.timestamp';这与sql_mode = only_full_group_by不兼容-查询:SELECT COUNT(*)作为尝试,SUM(elapsed)作为经过,total,userid,timestamp,questionid,answerid,SUM(正确)为正确,经过,ipaddress from gameWhere时间戳> = DATE_SUB (现在(),间隔1天)和用户ID = 1
在这种情况下,GROUP BY中缺少表达式#4。
对于localhost/wampserver 3,我们可以设置sql-mode = user_mode来删除此错误:
click on wamp icon -> MySql -> MySql Setting -> sql-mode -> user_mode
Run Code Online (Sandbox Code Playgroud)
然后重启wamp或apache