SELECT列表不在GROUP BY子句中,并且包含未聚合的列…与sql_mode = only_full_group_by不兼容


115

我在装有WAMP Server的Windows PC上使用MySQL 5.7.13

这是我的问题是执行此查询时

SELECT *
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND
      `status` = 'Active'
GROUP BY `proof_type`

总是会出现这样的错误

SELECT列表的表达式#1不在GROUP BY子句中,并且包含未聚合的列'returntr_prod.tbl_customer_pod_uploads.id',该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by不兼容

能否请您告诉我最好的解决方案...

我需要像这样的结果

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| id | user_id | load_id | bill_id | latitude | langitude | proof_type | document_type | file_name    | is_private | status | createdon           | updatedon           |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
|  1 |       1 | 78      | 1       | 21.1212  | 21.5454   |          1 |             1 | id_Card.docx |          0 | Active | 2017-01-27 11:30:11 | 2017-01-27 11:30:14 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+

12
不要使用SELECT *
shmosel


这样说SELECT ID FROM tbl_customer_pod_uploadsWHERE load_id=' statusproof_type
78'AND

2
如果要与旧查询兼容,可以关闭only_full_group_bySQL模式。
巴尔(Barmar)'17年

4
尝试使用ANY_VALUE(proof_type): dev.mysql.com/doc/refman/5.7/en/group-by-handling.html SELECT *,ANY_VALUE(proof_type)FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= '主动' GROUP BYproof_type
AlexGach

Answers:


228

这个

SELECT列表的表达式#1不在GROUP BY子句中,并且包含未聚合的列'returntr_prod.tbl_customer_pod_uploads.id',该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by不兼容

只需通过以下命令在MySQL中更改sql模式即可解决,

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

这也对我有用。我用了它,因为在我的项目中有很多这样的查询,所以我只是将此sql模式更改为only_full_group_by

谢谢... :-)


14
这个对我有用!。你救了我的一天。记得重新启动MYSQL服务
marcode_ely

2
如果我使用Codeigniter并想在模型中执行,那我将如何使用它?可以帮我 ?@marcode_ely
DhavalThakor

@DhavalThakor,一旦在服务器中运行此查询,就无需一次又一次地运行。因此您无需将其放入模型中
Dhanu K

2
MySQL 5.7.29,不需要重新启动服务
Taavi

我正在使用服务器版本:5.7.31-0ubuntu0.16.04.1-(Ubuntu),每当我启动计算机时,每次都进行设置,是否有针对此的永久修复程序?
Arpita Hunka

71

only_full_group_by开启MySQL 模式后,表示使用时将应用严格的ANSI SQL规则GROUP BY。关于您的查询,这意味着如果您GROUP BY在该proof_type列中,那么您只能选择两件事:

  • proof_type列或
  • 其他任何列的汇总


通过其他列的“聚合”,我的意思是使用诸如MIN(),的聚合函数MAX(),或AVG()与另一列一起使用。因此,在您的情况下,以下查询将有效:

SELECT proof_type,
       MAX(id) AS max_id,
       MAX(some_col),
       MIN(some_other_col)
FROM tbl_customer_pod_uploads
WHERE load_id = '78' AND
      status = 'Active'
GROUP BY proof_type

绝大多数的MySQL GROUP BY我在SO上看到问题都关闭了严格模式,因此查询正在运行,但结果不正确。在您的情况下,查询根本不会运行,从而迫使您考虑您真正想做的事情。

注意:ANSI SQL GROUP BY通过还包括功能上依赖于所选列的列,扩展了允许选择的范围。功能依赖项的一个示例是按表中的主键列进行分组。由于保证每个记录的主键都是唯一的,因此任何其他列的值也将确定。MySQL是允许这样做的数据库之一(SQL Server和Oracle不支持AFAIK)。


2
请注意:结果不是不正确的(遵循MySQL规则),但这是不可预测的,这意味着不属于group by且未聚合(且在功能上不依赖)的列将从对应的组返回“ random”值。手册指出:“服务器可以从每个组中自由选择任何值”
Pred

违反严格分组并不一定会产生错误的结果。我通常在保证字段相同(例如一对多联接)时执行此操作。即使不能保证,选择任意行通常也不再错误,然后再使用聚合函数或添加分组级别。
shmosel

1
为我+1。我不知道为什么上面的“已接受”答案已被接受。您的方法是正确的方法,可接受的答案是通常的hacky修复,将来会导致更多问题。
Jcov

1
@Jcov ...,我不同意您的评论+1。关闭ANSI限制GROUP BY几乎总是一个坏主意。如此众多的用户正在接受错误的建议并使用它,这使我感到恐惧。
Tim Biegeleisen

1
@TimBiegeleisen欢迎使用现代复制+粘贴开发。“我不需要思考,一个从不可靠的地方读过随机东西的人已经为我做了思考。”
Jcov

38

使用任何一种解决方案

(1)PHPMyAdmin

如果您使用的是phpMyAdmin ,请按照以下屏幕截图中所述更改“ sql_mode ”设置。 在此处输入图片说明

编辑“ SQL模式”变量,然后从值中删除“ ONLY_FULL_GROUP_BY”文本

(2)SQL /命令提示符 运行以下命令。

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

(3)**不要使用SELECT ***

在SELECT查询中使用相关列。相关的均值列,这些列要么出现在“ group by”子句中,要么出现在具有聚合函数(MAX,MIN,SUM,COUNT等)的列中


重要的提示

使用point(1)或point(2)进行的更改不会永久设置,并且每次重新启动后都会还原。

因此,您应该在配置文件中进行设置(例如[mysqld]部分中的/etc/mysql/my.cnf),以使更改在MySQL重新启动后仍然有效:

配置文件:/etc/mysql/my.cnf

变量名称:sql_mode sql-mode


19

下面的方法解决了我的问题:

在Ubuntu

类型: sudo vi /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退出输入模式

Type :wq to save and close vim.

键入sudo service mysql restart以重新启动MySQL。


1
谢谢,它有效!在cent os,whm中,my.cnf位于sudo vi /etc/my.cnf
Reejesh PK

17

您可以 通过某些命令禁用 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';

9

为了使查询在SQL92中合法,必须从选择列表中省略name列或在GROUP BY子句中命名。

如果SQL99和更高版本在功能上依赖于GROUP BY列,则每个非可选功能T301都允许此类非聚合:如果name和custid之间存在这种关系,则查询合法。例如,客户是客户的主键时就是这种情况。

MySQL 5.7.5及更高版本实现了对功能依赖性的检测。如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下),则MySQL拒绝查询,其中选择列表,HAVING条件或ORDER BY列表引用未在GROUP BY子句中命名且在功能上不依赖于它们的未聚合列。

通过MySQL :: MySQL 5.7参考手册:: 12.19.3 MySQL对GROUP BY的处理

您可以通过使用以下命令更改sql模式来解决此问题:

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

并且...记得重新连接数据库!!!


9

在Ubuntu中

第1步:

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

步骤2:转到最后一行并添加以下内容

sql_mode = ""

步骤3:储存

步骤4:重新启动mysql服务器。



3

如果您使用的是PhpMyAdmin,请搜索“ SQL模式”,然后取下值:ONLY_FULL_GROUP_BY,这样做就可以了。


2

从外观上看,我认为按多个列/字段分组不会损害您的结果。您为什么不尝试通过以下方式添加到群组:

GROUP BY `proof_type`, `id`

这将proof_type首先分组id。我希望这不会改变结果。在某些/大多数情况下,按多列分组会导致错误的结果。


2
> sudo nano /etc/mysql/my.cnf

在下面输入

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart

2

嗨,您不必使用所有列,而只需使用即可ANY_VALUE(column_name)。运行良好。只是检查一下。

例如:

SELECT proof_type,any_value("customer_name") as customer_name
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND `status` = 'Active' GROUP BY `proof_type`

1
  1. 登录到phpMyAdmin
  2. 导航到:服务器:localhost:3306,并且不选择任何数据库
  3. 单击顶部菜单中的变量
  4. 搜索“ sql模式”并将相应的值编辑为:NO_ENGINE_SUBSTITUTION

就这样。

我在Ec2中做到了,它就像魅力一样工作。


1

这是永久设置它的快速简便的方法

注意:运行SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); 是临时的,在服务器重新启动时,您仍然会遇到错误。要永久解决此问题,请执行以下操作

  1. 以root身份登录到服务器
  2. 在您的终端运行中 wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. 通过运行使脚本可执行 chmod +x disable-strict-mode.sh
  4. 通过运行来运行脚本 ./disable-strict-mode.sh

完成后,将对mysql进行更改,然后重新启动


0

MySQL 8.0更新

sql-mode将不会拥有NO_AUTO_CREATE_USER它,因为它已如此处所述被删除- 如何在mysql-8中设置sql-mode-in-my-cnf

[mysqld]
sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

另外,如果某人没有my.cnf文件,那么他们会在其中创建一个新文件/etc/my.cnf,然后添加上述行。


-2

在您的中my.ini,编写以下代码:

[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"

取决于您的版本。要么:

[mysqld]
sql_mode = ""

或简单地删除此: ONLY_FULL_GROUP_BY


-2

打开WAMP面板,然后打开MySQL配置文件。在其中搜索“ sql_mode”(如果找到),将其设置为“”,否则,将sql_mode =“”添加到文件中。

重新启动MySQL服务器,一切顺利...

快乐的编码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.