在 MySql 中执行查询时出现与 only_full_group_by 相关的错误
Error related to only_full_group_by when executing a query in MySql
我已经升级了我的系统,并为我正在开发的 Web 应用程序安装了 MySql 5.7.9 和 php。我有一个动态创建的查询,当 运行 在 MySql 的旧版本中时它工作正常。自从升级到 5.7 我得到这个错误:
Expression #1 of SELECT list is not in GROUP BY clause and contains
nonaggregated column 'support_desk.mod_users_groups.group_id' which is
not functionally dependent on columns in GROUP BY clause; this is
incompatible with 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
选项吗,还是我需要做其他事情?
如果您需要更多信息,请告诉我。
我只想将 group_id
添加到 GROUP BY
。
当 SELECT
ing 一个不属于 GROUP BY
的列时,组内该列可能有多个值,但单个列只有 space结果中的价值。因此,数据库通常 需要被准确告知如何将这些多个值变成一个值。通常,这是通过 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
,你可能会发现你现在得到比以前更多的结果,因为具有相同名称的组现在将在结果中有单独的行。对我来说,这比隐藏这些重复的组要好,因为数据库已经悄悄地任意选择了一个值!
当涉及多个 table 时,用 table 名称或别名限定所有列也是一种很好的做法...
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 8 不接受 NO_AUTO_CREATE_USER
所以需要删除。
如果您不想对当前查询进行任何更改,请按照以下步骤操作 -
- vagrant ssh 进入你的盒子
- 类型:
sudo vim /etc/mysql/my.cnf
- 滚动到文件底部并键入
A
进入插入模式
复制粘贴
[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
键入 esc
退出输入模式
- 键入
:wq
以保存并关闭 vim。
- 键入
sudo service mysql restart
以重新启动 MySQL。
您可以按照其他答案中的说明关闭警告消息,或者您可以了解发生了什么并修复它。
As of MySQL 5.7.5, the default SQL mode includes ONLY_FULL_GROUP_BY 这意味着当您对行进行分组然后从该组中选择某些内容时,您需要 明确说明应该从哪一行 中进行选择。
Mysql 需要知道您要查找组中的哪一行,这给了您两个选择
- 您还可以将您想要的列添加到组语句
group by rect.color, rect.value
中,这在某些情况下可能是您想要的,否则会 return 重复您可能不想要的相同颜色的结果
- 您还可以使用 mysql 的 聚合函数 来指示您在
AVG()
MIN()
等组中查找的行 MAX()
complete list
- 最后,如果您确定组内的所有结果都相同,则可以使用
ANY_VALUE()
。 doc
这就是帮助我理解整个问题的原因:
下面是另一个有问题的查询示例。
有问题:
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 = #
在最后加上这个解决了:
GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress
注意:参见PHP中的错误信息,它告诉你问题出在哪里。
示例:
MySQL query error 1140: In aggregated query without GROUP BY, expression #4 of SELECT list contains nonaggregated column 'db.gameplay.timestamp'; this is incompatible with sql_mode=only_full_group_by - Query: 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 userid = 1
在这种情况下,表达式 #4 在 GROUP BY 中丢失。
我在 laravel homestead(我相信是 0.5.0)上使用 Laravel 5.3、mysql 5.7.12
即使明确设置编辑 /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
我仍然收到错误消息。
我不得不将 config/database.php
从 true
更改为 false
:
'mysql' => [
'strict' => false, //behave like 5.6
//'strict' => true //behave like 5.7
],
进一步阅读:
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
使用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 docs:
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;
对于mac:
1.Copy默认my-default.cnf为/etc/my.cnf
sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
2.Change sql_mode 在 my.cnf 中使用您最喜欢的编辑器并将其设置为此
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.Restart MySQL 服务器。
mysql.server restart
对于 localhost / wampserver 3 我们可以设置 sql-mode = user_mode 来消除这个错误:
click on wamp icon -> MySql -> MySql Setting -> sql-mode -> user_mode
然后重启 wamp 或 apache
抱歉没有使用您的确切 SQL
我用这个查询克服了 Mysql 警告。
SELECT count(*) AS cnt, `regions_id`
FROM regionables
WHERE `regionable_id` = '115' OR `regionable_id` = '714'
GROUP BY `regions_id`
HAVING cnt > 1
注意我的关键
count(*) AS cnt
如果您使用的是 wamp 3.0.6 或稳定版 2.5 以外的任何更高版本,您可能会遇到此问题,首先问题出在 sql 上。您必须相应地命名字段。但是还有另一种方法可以解决它。单击 wamp 的绿色图标。 mysql->mysql设置->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';
我会尽力向您解释此错误的含义。
从 MySQL 5.7.5 开始,默认启用选项 ONLY_FULL_GROUP_BY
。
因此,根据标准 SQL92 和更早版本:
does not permit queries for which the select list, HAVING condition,
or ORDER BY list refer to nonaggregated columns that are neither named
in the GROUP BY clause nor are functionally dependent on (uniquely
determined by) GROUP BY columns
因此,例如:
SELECT * FROM `users` GROUP BY `name`;
执行上述查询后,您将收到错误消息。
#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'testsite.user.id' which is not
functionally dependent on columns in GROUP BY clause; this is
incompatible with sql_mode=only_full_group_by
为什么?
因为MySQL不太明白,要从分组记录中检索哪些特定值,这就是重点。
I.E.假设您的 users
table:
中有此记录
并且您将执行上面显示的无效查询。
你会得到上面显示的错误,因为有 3 条记录名称为 John
,这很好,但是,它们都有不同的 email
字段值。
所以,MySQL 根本不明白在生成的分组记录中 return 他们中的哪一个。
您可以解决此问题,只需像这样更改您的查询:
SELECT `name` FROM `users` GROUP BY `name`
此外,您可能想向 SELECT 部分添加更多字段,但如果它们未聚合,则您不能这样做,但您可以使用拐杖(但非常不推荐):
SELECT ANY_VALUE(`id`), ANY_VALUE(`email`), `name` FROM `users` GROUP BY `name`
现在,您可能会问,为什么不推荐使用 ANY_VALUE
?
因为 MySQL 不确切知道要检索的分组记录的值,并且通过使用此函数,您要求它获取其中任何一个(在本例中,获取了名称为 John 的第一条记录的电子邮件)。
确切地说,我想不出任何关于为什么你会希望这种行为存在的想法。
请,如果你不明白我的意思,请阅读更多关于 MySQL 中分组的工作原理,它非常简单。
到最后,这是一个更简单但有效的查询。
如果你想根据可用年龄查询总用户数,你可能需要写下这个查询
SELECT `age`, COUNT(`age`) FROM `users` GROUP BY `age`;
根据 MySQL 规则完全有效。
依此类推
重要的是要了解问题到底是什么,然后才写下解决方案。
在文件中添加行(下面提到):/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
对我来说工作得很好。
服务器版本:5.7.18-0ubuntu0.16.04.1 - (Ubuntu)
如果您在使用 Symfony 使用 doctrine 查询生成器 时遇到此错误,并且如果此错误是由 顺序 :
注意 select
你想要 groupBy
的列,并使用 addGroupBy
而不是 groupBy
:
$query = $this->createQueryBuilder('smth')->addGroupBy('smth.mycolumn');
适用于 Symfony3 -
您可以在group_id
中添加一个unique index
;如果您确定 group_id
是唯一的。
无需修改查询即可解决您的问题。
迟到的答案,但答案中尚未提及。也许它应该完成已经很全面的可用答案。至少它确实解决了我不得不用太多字段拆分 table 的情况。
转到mysql或phpmyadmin和select数据库
然后简单地执行这个查询,它就会工作。
它对我来说很好用。
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
我不得不在 Ubuntu 18.04 上编辑以下文件:
/etc/mysql/mysql.conf.d/mysqld.cnf
与
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
和
sudo service mysql restart
上面的共识答案很好,但是如果您在修复 my.cnf 文件后在存储过程中遇到 运行 查询问题,请尝试再次加载您的 SP。
我怀疑 MySQL 一定是用最初设置的默认 only_full_group_by 编译了 SP。因此,即使我更改 my.cnf 并重新启动 mysqld,它对 SP 也没有影响,并且它们一直失败,并显示“SELECT list is not in GROUP BY clause and contains nonaggregated column ... which is not在功能上依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by".
不兼容
重新加载 SP 一定会导致它们在禁用 only_full_group_by 的情况下重新编译。之后,它们似乎按预期工作。
我已经升级了我的系统,并为我正在开发的 Web 应用程序安装了 MySql 5.7.9 和 php。我有一个动态创建的查询,当 运行 在 MySql 的旧版本中时它工作正常。自从升级到 5.7 我得到这个错误:
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'support_desk.mod_users_groups.group_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with 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
选项吗,还是我需要做其他事情?
如果您需要更多信息,请告诉我。
我只想将 group_id
添加到 GROUP BY
。
当 SELECT
ing 一个不属于 GROUP BY
的列时,组内该列可能有多个值,但单个列只有 space结果中的价值。因此,数据库通常 需要被准确告知如何将这些多个值变成一个值。通常,这是通过 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
,你可能会发现你现在得到比以前更多的结果,因为具有相同名称的组现在将在结果中有单独的行。对我来说,这比隐藏这些重复的组要好,因为数据库已经悄悄地任意选择了一个值!
当涉及多个 table 时,用 table 名称或别名限定所有列也是一种很好的做法...
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 8 不接受 NO_AUTO_CREATE_USER
所以需要删除。
如果您不想对当前查询进行任何更改,请按照以下步骤操作 -
- vagrant ssh 进入你的盒子
- 类型:
sudo vim /etc/mysql/my.cnf
- 滚动到文件底部并键入
A
进入插入模式 复制粘贴
[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
键入
esc
退出输入模式- 键入
:wq
以保存并关闭 vim。 - 键入
sudo service mysql restart
以重新启动 MySQL。
您可以按照其他答案中的说明关闭警告消息,或者您可以了解发生了什么并修复它。
As of MySQL 5.7.5, the default SQL mode includes ONLY_FULL_GROUP_BY 这意味着当您对行进行分组然后从该组中选择某些内容时,您需要 明确说明应该从哪一行 中进行选择。
Mysql 需要知道您要查找组中的哪一行,这给了您两个选择
- 您还可以将您想要的列添加到组语句
group by rect.color, rect.value
中,这在某些情况下可能是您想要的,否则会 return 重复您可能不想要的相同颜色的结果 - 您还可以使用 mysql 的 聚合函数 来指示您在
AVG()
MIN()
等组中查找的行MAX()
complete list - 最后,如果您确定组内的所有结果都相同,则可以使用
ANY_VALUE()
。 doc
这就是帮助我理解整个问题的原因:
下面是另一个有问题的查询示例。
有问题:
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 = #
在最后加上这个解决了:
GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress
注意:参见PHP中的错误信息,它告诉你问题出在哪里。
示例:
MySQL query error 1140: In aggregated query without GROUP BY, expression #4 of SELECT list contains nonaggregated column 'db.gameplay.timestamp'; this is incompatible with sql_mode=only_full_group_by - Query: 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 userid = 1
在这种情况下,表达式 #4 在 GROUP BY 中丢失。
我在 laravel homestead(我相信是 0.5.0)上使用 Laravel 5.3、mysql 5.7.12
即使明确设置编辑 /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
我仍然收到错误消息。
我不得不将 config/database.php
从 true
更改为 false
:
'mysql' => [
'strict' => false, //behave like 5.6
//'strict' => true //behave like 5.7
],
进一步阅读:
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
使用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 docs:
You can achieve the same effect without disabling
ONLY_FULL_GROUP_BY
by usingANY_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 theGROUP 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;
对于mac:
1.Copy默认my-default.cnf为/etc/my.cnf
sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
2.Change sql_mode 在 my.cnf 中使用您最喜欢的编辑器并将其设置为此
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.Restart MySQL 服务器。
mysql.server restart
对于 localhost / wampserver 3 我们可以设置 sql-mode = user_mode 来消除这个错误:
click on wamp icon -> MySql -> MySql Setting -> sql-mode -> user_mode
然后重启 wamp 或 apache
抱歉没有使用您的确切 SQL
我用这个查询克服了 Mysql 警告。
SELECT count(*) AS cnt, `regions_id`
FROM regionables
WHERE `regionable_id` = '115' OR `regionable_id` = '714'
GROUP BY `regions_id`
HAVING cnt > 1
注意我的关键
count(*) AS cnt
如果您使用的是 wamp 3.0.6 或稳定版 2.5 以外的任何更高版本,您可能会遇到此问题,首先问题出在 sql 上。您必须相应地命名字段。但是还有另一种方法可以解决它。单击 wamp 的绿色图标。 mysql->mysql设置->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';
我会尽力向您解释此错误的含义。
从 MySQL 5.7.5 开始,默认启用选项 ONLY_FULL_GROUP_BY
。
因此,根据标准 SQL92 和更早版本:
does not permit queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on (uniquely determined by) GROUP BY columns
因此,例如:
SELECT * FROM `users` GROUP BY `name`;
执行上述查询后,您将收到错误消息。
#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'testsite.user.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
为什么?
因为MySQL不太明白,要从分组记录中检索哪些特定值,这就是重点。
I.E.假设您的 users
table:
中有此记录
并且您将执行上面显示的无效查询。
你会得到上面显示的错误,因为有 3 条记录名称为 John
,这很好,但是,它们都有不同的 email
字段值。
所以,MySQL 根本不明白在生成的分组记录中 return 他们中的哪一个。
您可以解决此问题,只需像这样更改您的查询:
SELECT `name` FROM `users` GROUP BY `name`
此外,您可能想向 SELECT 部分添加更多字段,但如果它们未聚合,则您不能这样做,但您可以使用拐杖(但非常不推荐):
SELECT ANY_VALUE(`id`), ANY_VALUE(`email`), `name` FROM `users` GROUP BY `name`
现在,您可能会问,为什么不推荐使用 ANY_VALUE
?
因为 MySQL 不确切知道要检索的分组记录的值,并且通过使用此函数,您要求它获取其中任何一个(在本例中,获取了名称为 John 的第一条记录的电子邮件)。
确切地说,我想不出任何关于为什么你会希望这种行为存在的想法。
请,如果你不明白我的意思,请阅读更多关于 MySQL 中分组的工作原理,它非常简单。
到最后,这是一个更简单但有效的查询。
如果你想根据可用年龄查询总用户数,你可能需要写下这个查询
SELECT `age`, COUNT(`age`) FROM `users` GROUP BY `age`;
根据 MySQL 规则完全有效。
依此类推
重要的是要了解问题到底是什么,然后才写下解决方案。
在文件中添加行(下面提到):/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
对我来说工作得很好。 服务器版本:5.7.18-0ubuntu0.16.04.1 - (Ubuntu)
如果您在使用 Symfony 使用 doctrine 查询生成器 时遇到此错误,并且如果此错误是由 顺序 :
注意 select
你想要 groupBy
的列,并使用 addGroupBy
而不是 groupBy
:
$query = $this->createQueryBuilder('smth')->addGroupBy('smth.mycolumn');
适用于 Symfony3 -
您可以在group_id
中添加一个unique index
;如果您确定 group_id
是唯一的。
无需修改查询即可解决您的问题。
迟到的答案,但答案中尚未提及。也许它应该完成已经很全面的可用答案。至少它确实解决了我不得不用太多字段拆分 table 的情况。
转到mysql或phpmyadmin和select数据库 然后简单地执行这个查询,它就会工作。 它对我来说很好用。
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
我不得不在 Ubuntu 18.04 上编辑以下文件:
/etc/mysql/mysql.conf.d/mysqld.cnf
与
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
和
sudo service mysql restart
上面的共识答案很好,但是如果您在修复 my.cnf 文件后在存储过程中遇到 运行 查询问题,请尝试再次加载您的 SP。
我怀疑 MySQL 一定是用最初设置的默认 only_full_group_by 编译了 SP。因此,即使我更改 my.cnf 并重新启动 mysqld,它对 SP 也没有影响,并且它们一直失败,并显示“SELECT list is not in GROUP BY clause and contains nonaggregated column ... which is not在功能上依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by".
不兼容重新加载 SP 一定会导致它们在禁用 only_full_group_by 的情况下重新编译。之后,它们似乎按预期工作。