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

Dha*_*u K 38 mysql group-by mysql-error-1055

AM在我的带有WAMP服务器的Windows PC上使用MySQL 5.7.13

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

SELECT *
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND
      `status` = 'Active'
GROUP BY `proof_type`
Run Code Online (Sandbox Code Playgroud)

我总是得到这样的错误

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 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

Dha*_*u K 115

这个

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',''));
Run Code Online (Sandbox Code Playgroud)

这对我来说太有用了..我在我的项目中使用了这个因为有很多这样的查询所以只需更改这个sql模式onli_full_group_by

谢谢... :-)

  • 我正在使用服务器版本:5.7.31-0ubuntu0.16.04.1 - (Ubuntu),每当我启动我的机器时,我每次都会设置它,对此有任何永久修复吗? (5认同)
  • 使用set语句时,此更改仅适用于运行时。当服务器重新启动时,您的更改将被覆盖。您可以参考[mysql中的sql模式](https://blog.abhisheksharma.online/sql-mode-in-mysql/)进行永久更改,也可以参考[fix only_full_group_by](https://blog.abhisheksharma.online / fix-error-select-list不在子句中,按子句选择列表包含与SQL_modeonly_full_group_by-in-aggregated query-without-group-by的非聚集列不兼容 (3认同)
  • 这个对我有用!.你救了我的一天.记得重新启动MYSQL SERVICE (3认同)
  • 如果我正在使用 codeigniter 并且我想在模型中执行,那么我将如何使用它?可以帮我 ?@marcode_ely (3认同)
  • MySQL 5.7.29,不需要重启服务 (3认同)
  • 注意:更改 sql_mode 不会影响存储过程。所以需要删除并再次执行SP才能生效 (3认同)
  • 向下滚动并查看答案(例如 /sf/answers/4542308081/),以了解为什么存在此限制。除非您想要随机结果并且知道自己在做什么,否则不要遵循此答案。 (3认同)

Ahm*_*aki 44

only_full_group_by = on告诉 MySQL 引擎:GROUP BY当你对显示什么结果有疑问并抛出错误时不要申请。仅在Group By明确告诉您要做什么时才应用它。即当Group By是完整的和完美的!

only_full_group_by = off告诉 MySQL 引擎:始终应用GROUP BY,如果您对选择的结果有疑问,请随机选择一个!

如果使用GROUP BY得当,您不必关闭它 !

例子:

表:用户

 id   |  name
----------------
  1      ali
  2      john
  3      ali
Run Code Online (Sandbox Code Playgroud)

在列GROUP BY上使用时name

SELECT * FROM users GROUP BY name;
Run Code Online (Sandbox Code Playgroud)

有两种可能的结果:

  1      ali
  2      john     
Run Code Online (Sandbox Code Playgroud)

或者

  2      john
  3      ali
Run Code Online (Sandbox Code Playgroud)

MYSQL不知道选择什么结果!因为有不同的ids 但两者都有name=ali

解决方案1:

只选择name字段:

SELECT name FROM users GROUP BY name;
Run Code Online (Sandbox Code Playgroud)

结果:

  ali
  john     
Run Code Online (Sandbox Code Playgroud)

这是一个完美的解决方案。删除令人GROUP BY困惑的列。这意味着你知道你在做什么。通常,您不需要
这些列,但如果您需要它们,请转到解决方案 3!

解决方案2:

关闭only_full_group_by。MYSQL 将随机选择两种可能的结果之一!(如果你真的不关心id它会选择什么也没关系,但记得在你查询后立即关闭它以防止未来 groupBys 中的意外行为)

解决方案3

使用Aggregate类似MIN(),的函数MAX()来帮助 MYSQL 决定它必须选择什么。

例如:

SELECT MAX(id), name FROM users GROUP BY name;
Run Code Online (Sandbox Code Playgroud)

结果:

  2      john     
  3      ali
Run Code Online (Sandbox Code Playgroud)

它将选择ali具有最大值的行id

  • 这个答案帮助我最好地理解了它。谢谢。 (3认同)
  • 感谢您对这个问题的良好而准确的解释。 (2认同)

Tim*_*sen 33

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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 对我来说+1。我不知道为什么上面的“已接受”答案已被接受。您的方法是正确的方法,接受的答案是通常的黑客修复,这将导致将来出现更多问题。 (6认同)
  • 请注意:结果没有错误(它遵循 MySQL 规则),但它是不可预测的,这意味着,不属于 group by 且未聚合(且不依赖于功能)的列将从相应的组返回一个“随机”值。正如手册所述:“服务器可以自由地从每个组中选择任何值” (3认同)
  • @Jcov ...我不能同意你的评论更多+1。关闭对“GROUP BY”的 ANSI 限制几乎总是一个坏主意。让我害怕的是,这么多用户接受了错误的建议并使用它。 (3认同)
  • @TimBiegeleisen 欢迎来到现代复制+粘贴开发。“我不需要思考,一个从不可靠的来源随机阅读过一些东西的人已经为我完成了思考”。 (2认同)
  • 这应该是公认的答案。它回答了最佳解决方案的问题,并解释了为什么它在当前设置中不起作用。并非所有开发人员都有权访问这些设置或允许更改这些设置。 (2认同)

小智 20

在 Ubuntu 中

第1步:

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
Run Code Online (Sandbox Code Playgroud)

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

sql_mode = ""
Run Code Online (Sandbox Code Playgroud)

第 3 步:保存

第四步:重启mysql服务器。

  • 救生员的答案。 (2认同)

Rak*_*oni 14

使用任何一种解决方案

(1)PHPMyAdmin

如果您正在使用phpMyAdmin,则更改" sql_mode "设置,如下面的屏幕截图所示. 在此输入图像描述

编辑"sql mode"变量并从值中删除"ONLY_FULL_GROUP_BY"文本

(2)命令提示符 运行以下命令.

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)

(3)不要使用SELECT*

在SELECT查询中使用相关列.相关意味着列,或者是"group by"子句或具有聚合函数的列(MAX,MIN,SUM,COUNT等)


重要的提示

使用point(1)OR point(2)所做的更改不会永久设置,并且每次重启后都会恢复.

所以你应该在配置文件中设置它(例如[mysqld]部分中的/etc/mysql/my.cnf),以便在MySQL重启后更改仍然有效:

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

变量名:sql_mode sql-mode

  • (1) 使用命令“chmod”更改文件my.cnf的文件权限。(2) 在 my.cnf 中执行更改 (3) 再次将其设置为只读(使用“chmod”再次更改文件权限) (4) 重新启动 mysql (2认同)

siv*_*cky 14

嗨,不要使用所有列,只需使用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`
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用。[MySQL 文档](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_any-value) 状态“当 ONLY_FULL_GROUP_BY SQL 模式为启用,适用于 MySQL 因 MySQL 无法确定的原因而拒绝您知道有效的查询的情况。” 因此,如果您的数据库用户无权关闭“ONLY_FULL_GROUP_BY”,这是另一个需要考虑的选项。 (3认同)

Ani*_*pta 13

您可以 通过某些命令禁用 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';
Run Code Online (Sandbox Code Playgroud)


gau*_*tam 11

MySQL 8.0 更新

sql-mode不会有,NO_AUTO_CREATE_USER因为它已被删除,如此处所述 - how-to-set-sql-mode-in-my-cnf-in-mysql-8

[mysqld]
sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
Run Code Online (Sandbox Code Playgroud)

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


小智 10

两种解决方案:

a) 使用

设置全局 sql_mode=(选择替换(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

b) 通过使用 ANY_VALUE() 引用非聚合列,无需禁用 ONLY_FULL_GROUP_BY 即可达到相同的效果。

ANY_VALUE(值)


小智 8

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

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

MySQL 5.7.5及更高版本实现了对功能依赖性的检测。如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下为MySQL),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',''));

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


小智 8

转到 phpmyadmin 并打开控制台并执行此请求

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)


Sun*_*dar 8

> sudo nano /etc/mysql/my.cnf
Run Code Online (Sandbox Code Playgroud)

在下面输入

[mysqld]
sql_mode = ""
Run Code Online (Sandbox Code Playgroud)

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart
Run Code Online (Sandbox Code Playgroud)


hex*_*had 8

就我而言,这是我旧的sql_mode

sql_mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令检查sql_mode

show variables like "sql_mode";
Run Code Online (Sandbox Code Playgroud)

然后我将其设置为这样

SET sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
Run Code Online (Sandbox Code Playgroud)


小智 7

从它的外观来看,我认为按多个列/字段分组不会损害您的结果。你为什么不尝试通过这样的方式添加到组中:

GROUP BY `proof_type`, `id`
Run Code Online (Sandbox Code Playgroud)

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


Bha*_*ani 7

我遇到了这个问题,以下查询还不够

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)

因为我使用的是存储过程。执行此查询后,我不得不放弃该过程并再次创建.

  • 做得好!谢谢 (2认同)

小智 6

我的部分数据库粉碎有类似的问题。我所做的是通过 PHPStorm 数据库控制台更改数据库中的参数,如下所示:

   SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)

现在像魅力一样工作


Nan*_*mar 6

在运行查询之前运行以下查询

SET SQL_MODE = '';
Run Code Online (Sandbox Code Playgroud)


don*_*key 6

步骤1.检查sql模式:

SELECT @@GLOBAL.sql_mode;
Run Code Online (Sandbox Code Playgroud)

步骤2.在/etc/mysql/conf.d/目录下创建新的配置文件:

sudo nano /etc/mysql/conf.d/disable_strict_mode.cnf
Run Code Online (Sandbox Code Playgroud)

在编辑器中输入以下文本:

[mysqld]

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
Run Code Online (Sandbox Code Playgroud)

步骤3.重新启动MySQL:

sudo service mysql restart
Run Code Online (Sandbox Code Playgroud)

步骤 4. 确认更改:

SELECT @@GLOBAL.sql_mode;
Run Code Online (Sandbox Code Playgroud)


小智 5

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

在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
Run Code Online (Sandbox Code Playgroud)

键入esc退出输入模式

Type :wq to save and close vim.
Run Code Online (Sandbox Code Playgroud)

输入sudo service mysql restart重启MySQL。

  • 谢谢,它成功了!在 Cent os、whm 中,my.cnf 位于 sudo vi /etc/my.cnf (4认同)

小智 5

如果您使用的是 PhpMyAdmin,请搜索“SQL 模式”并去掉值:ONLY_FULL_GROUP_BY, just did and it 没问题。