#1055 - SELECT 列表的表达式不在 GROUP BY 子句中,并且包含非聚合列,这与 sql_mode=only_full_group_by 不兼容
Posted
技术标签:
【中文标题】#1055 - SELECT 列表的表达式不在 GROUP BY 子句中,并且包含非聚合列,这与 sql_mode=only_full_group_by 不兼容【英文标题】:#1055 - Expression of SELECT list is not in GROUP BY clause and contains nonaggregated column this is incompatible with sql_mode=only_full_group_by 【发布时间】:2016-10-23 10:24:52 【问题描述】:我的查询:
select libelle,credit_initial,disponible_v,sum(montant) as montant
FROM fiche,annee,type where type.id_type=annee.id_type and annee.id_annee=fiche.id_annee
and annee = year(current_timestamp) GROUP BY libelle order by libelle asc
mysql 5.7.9 运行查询没有任何问题,但 mysql 5.7.12
显示上面的错误你能帮我解决一下吗
【问题讨论】:
它期望您在 group by 声明中包含 libelle、credit_initila 和 disponible_v mechanics.flite.com/blog/2013/02/12/… I am getting an error in MySql related to only_full_group_by when executing a query的可能重复 问题出在mysql本身而不是查询 【参考方案1】:您必须通过 NOT IN
group by
子句进行聚合。
所以,有两个选项...将 Credit_Initial 和 Disponible_v 添加到 group by
或
如果您知道这些值无论如何都是恒定的并且没有其他影响,请将它们更改为 MAX( Credit_Initial ) as Credit_Initial, MAX( Disponible_v ) as Disponible_v
。
【讨论】:
【参考方案2】:您需要在 GROUP BY
子句中指定所有未用于聚合函数的列,如下所示:
select libelle,credit_initial,disponible_v,sum(montant) as montant
FROM fiche,annee,type where type.id_type=annee.id_type and annee.id_annee=fiche.id_annee
and annee = year(current_timestamp) GROUP BY libelle,credit_initial,disponible_v order by libelle asc
full_group_by
模式基本上让你编写更惯用的 SQL。如果您愿意,可以关闭此设置。 MySQL Documentation 中概述了执行此操作的不同方法。这是我上面所说的 MySQL 的定义:
MySQL 5.7.5 及更高版本实现了功能依赖检测。如果 ONLY_FULL_GROUP_BY SQL 模式已启用(默认情况下), MySQL 拒绝选择列表、HAVING 条件或 ORDER BY 列表指的是未在其中命名的非聚合列 GROUP BY 子句在功能上也不依赖于它们。 (前 5.7.5,MySQL不检测函数依赖,默认不启用ONLY_FULL_GROUP_BY。对于描述 5.7.5 之前的行为,请参阅 MySQL 5.6 参考手册。)
您收到错误是因为您使用的是 版本
【讨论】:
我正在使用 ubuntu mysql 5.7.12 任何其他可用选项,因为我有其他查询,我需要如何仅将完整组转换为 of 如果您当前正在编写数据库逻辑,这是一个实际的解决方案,因为这将使您的代码更加精确并减少输出中的很多不确定性。【参考方案3】:基于 5.7.5 ONLY_FULL_GROUP_BY 的默认配置 您应该使用组中的所有非聚合列
select libelle,credit_initial,disponible_v,sum(montant) as montant
FROM fiche,annee,type
where type.id_type=annee.id_type
and annee.id_annee=fiche.id_annee
and annee = year(current_timestamp)
GROUP BY libelle,credit_initial,disponible_v order by libelle asc
【讨论】:
它没有任何意义,如果您按某个 id 计数(指向另一个表的索引),那么您为什么需要添加与组中计数无关的其他列,特别是如果您不想按这些列分组 @fdsfdsfdsfds 这是该子句强制您执行的操作。 ONLY_FULL_GROUP_BY 要求所有不由聚合函数管理的列在组中声明 .. OP 提供的这些解决方案更改了 ONLY_FULL_GROUP_BY sql_mode 但这不是正确的 sql(如果默认情况下 mysql 允许直到 5.7)跨度> 【参考方案4】:我很难让它工作我已经测试过它并且它在灯服务器 mysql 版本 5.12 上工作
所以,成功的步骤:
sudo vim /etc/mysql/conf.d/mysql.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
到文件底部
-
保存并退出输入模式
sudo service mysql restart
重启 MySQL。
完成!
【讨论】:
我解决了同样的问题,只删除:STRICT_TRANS_TABLES from the sql_mode= string in /etc/mysql/my.cnf in Ubuntu 16.04 (MySQL 5.7) and restart mysql: systemctl restart mysql 对于那些找不到此文件的人 我的文件名为 my.ini 与 mysql.cnf 相同 在文档中有一些关于这里发生的事情的信息:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html 并且比编辑 mysql.cnf(或者只是按照 gr1zzly be4r 和 scaisEdge 建议的那样修复 sql)的解决方法不那么激烈: https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value 不要像我一样将[mysqld]
与[mysql]
混淆。
这个答案是错误的。正确答案是修复查询。【参考方案5】:
这对我有用:
mysql -u root -p
mysql > SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
第一步可能需要 sudo:
sudo mysql -u root -p
【讨论】:
最后这也是唯一对我有用的东西 我开始认为这个解决方案只会持续到 mysql 重新启动。接受的解决方案更好。 Henry,这种方法的优点是可以选择性地应用。如果修改 my.cnf,服务器上的每个应用程序和数据库都会受到影响。 OTOH,如果应用程序/帐户具有 SET GLOBAL 权限(不确定但可以实现),您可以在运行其他查询之前在数据库准备阶段从应用程序运行此查询。它用一个违反 FULL_ORDER_GROUP_BY 的旧旧应用程序保存了我的培根……我只是在数据库连接初始化后立即调用它…… 如果 MySQL 重新启动,问题将再次出现。所以这不是永久修复。 我使用 uniserverZero,打开控制台并编写代码,现在可以工作了,谢谢【参考方案6】:只要去窗口底部托盘点击wamp图标,点击mysql->my.ini,然后有选项;sql-mode="" 取消注释这使它像 sql-mode="" 并重新启动 wamp 为我工作
【讨论】:
【参考方案7】:您可以禁用 sql_mode=only_full_group_by 通过某些命令,您可以通过终端或 MySql IDE 尝试此操作
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】:解决方案 1:从 mysql 控制台中删除 ONLY_FULL_GROUP_BY
mysql > SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
你可以在这里阅读更多
解决方案 2:从 phpmyadmin 中删除 ONLY_FULL_GROUP_BY
Open phpmyadmin & select localhost
Click on menu Variables & scroll down for sql mode
Click on edit button to change the values & remove ONLY_FULL_GROUP_BY & click on save.
【讨论】:
嗨 Tauqueer,请将 mysql 行格式化为代码。此外,您还缺少引用其他阅读材料的链接。 如果 MySQL 重新启动,问题将再次出现。所以这不是永久修复。【参考方案9】:8.0+ 版本也发生了同样的事情。默认情况下,在 8.0+ 版本中,它默认为“启用”。这是链接official document reference
如果是 5.6+、5.7+ 版本,默认禁用“ONLY_FULL_GROUP_BY”属性。
要禁用它,请按照@Miloud BAKTETE 建议的相同步骤操作
【讨论】:
【参考方案10】:所以让我们充分理解,假设您有一个在 localhost 下工作但在生产模式下不工作的查询,这是因为在MySQL 5.7 and above
他们决定默认激活sql_mode=only_full_group_by
,基本上这是一个严格模式阻止您选择非聚合字段。
这是查询(在本地工作但不能在生产模式下工作):
SELECT post.*, YEAR(created_at) as year
FROM post
GROUP BY year
SELECT post.id, YEAR(created_at) as year // This will generate an error since there are many ids
FROM post
GROUP BY year
要验证sql_mode=only_full_group_by
是否被激活,您应该执行以下查询:
SELECT @@sql_mode; //localhost
输出:IGNORE_SPACE, STRICT_TRANS, ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
(如果你没有看到它,则表示它已停用)
但是如果在生产模式下尝试,或者在某个地方出现错误,它应该被激活:
SELECT @@sql_mode; //production
输出: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO...
我们在这里寻找的是ONLY_FULL_GROUP_BY
。
否则,如果您使用的是 phpMyAdmin,请转到 -> Variables
并搜索 sql_mode
让我们以我们之前的例子来适应它:
SELECT MIN(post.id), YEAR(created_at) as year //Here we are solving the problem with MIN()
FROM post
GROUP BY year
MAX()
也是如此
如果我们想要所有的 ID,我们将需要:
SELECT GROUP_CONCAT(post.id SEPARATOR ','), YEAR(created_at) as year
FROM post
GROUP BY year
或其他新增功能:
SELECT ANY_VALUE(post.id), YEAR(created_at) as year
FROM post
GROUP BY year
⚠️ MariaDB 不存在 ANY_VALUE
如果你想要所有字段,那么你可以使用相同的:
SELECT ANY_VALUE(post.id), ANY_VALUE(post.slug), ANY_VALUE(post.content) YEAR(created_at) as year
FROM post
GROUP BY year
❌ 要停用sql_mode=only_full_group_by
,您需要执行以下查询:
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
对小说感到抱歉,希望对您有所帮助。
【讨论】:
【参考方案11】:另外,如果您使用 MySql 8+,请在控制台中尝试以下命令:
打开 MySql 控制台
mysql -u user_name -p
并设置全局SQL模式
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_ENGINE_SUBSTITUTION';
【讨论】:
以上是关于#1055 - SELECT 列表的表达式不在 GROUP BY 子句中,并且包含非聚合列,这与 sql_mode=only_full_group_by 不兼容的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 错误:SELECT 列表不在 GROUP BY 子句中
MySQL 5.0.12 - 列表不在 GROUP BY 子句中并且包含非聚合列?