287

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`

我总是遇到这样的错误

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 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
4

26 回答 26

442

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

或者简单地包括 SELECT 语句指定的 GROUP BY 子句中的所有列。sql_mode 可以保持启用状态。

谢谢你... :-)

于 2017-01-27T05:44:32.083 回答
159

当 MySQL 的only_full_group_by模式打开时,意味着在使用GROUP BY. 关于你的查询,这意味着如果你GROUP BYproof_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

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

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

于 2017-01-27T05:34:19.303 回答
137

MySql 引擎中有一个系统变量ONLY_FULL_GROUP_BY

从 Mysql 版本 5.7.5 开始ONLY_FULL_GROUP_BY默认启用 SQL 模式

在版本 5.7.5 之前ONLY_FULL_GROUP_BY默认情况下未启用。

如果ONLY_FULL_GROUP_BY启用了 SQL 模式(默认情况下从版本 5.7.5 开始),MySQL 拒绝选择列表、HAVING条件或ORDER BY列表引用非聚合列的查询,这些列既不在GROUP BY子句中命名,也不在功能上依赖于他们。

要解决问题,请使用任何一种解决方案(以下 3 种)

(1) PHPMyAdmin

禁用ONLY_FULL_GROUP_BY模式

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

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

或者

(2) SQL/命令提示符

ONLY_FULL_GROUP_BY通过运行以下命令禁用:模式。

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

或者

(3) 不要使用SELECT *

不要禁用ONLY_FULL_GROUP_BY模式,但

SELECT在查询中使用相关列。相关表示列,它们要么在group by子句中出现,要么带有聚合函数的列(MAXMINSUMCOUNT


重要的提示

通过 using 所做的更改point(1) OR point(2)不会永久设置它,它会在每次重新启动后恢复。

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

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

变量名sql_mode sql-mode

从值中删除单词ONLY_FULL_GROUP_BY并保存文件。

注意:如果您在配置文件中没有找到sql_mode变量,请在文件末尾插入以下 2 行

[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
于 2018-08-01T09:01:18.217 回答
70

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

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

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

例子:

表:用户

 id   |  name
----------------
  1      ali
  2      john
  3      ali

当您GROUP BYname列上使用时:

SELECT * FROM users GROUP BY name;

有两种可能的结果:

  1      ali
  2      john     

或者

  2      john
  3      ali

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

解决方案1:

只选择name字段:

SELECT name FROM users GROUP BY name;

结果:

  ali
  john     

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

解决方案2:

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

解决方案3

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

例如:

SELECT MAX(id), name FROM users GROUP BY name;

结果:

  2      john     
  3      ali

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

于 2020-11-18T09:16:17.327 回答
39

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

在 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。

于 2019-09-04T06:19:43.080 回答
27

您可以通过某些命令禁用 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';
于 2017-08-29T18:17:36.000 回答
21

在 Ubuntu 中

第1步:

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

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

sql_mode = ""

第 3 步:保存

第四步:重启mysql服务器。

于 2020-01-24T03:46:32.767 回答
19

您好,不要使用所有列,只需使用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`
于 2020-01-31T14:01:49.603 回答
12

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

如果它们在功能上依赖于 GROUP BY 列,则 SQL99 和更高版本允许根据可选功能 T301 进行此类非聚合:如果 name 和 custid 之间存在这种关系,则查询是合法的。例如,如果客户的主键被托管,就会出现这种情况。

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

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

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

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

还有……记得重新连接数据库!!!

于 2017-10-19T07:58:07.533 回答
10

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

GROUP BY `proof_type`, `id`

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

于 2017-11-13T05:07:39.957 回答
8

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

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
于 2020-04-23T17:32:13.887 回答
8
> sudo nano /etc/mysql/my.cnf

在下面输入

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart
于 2020-04-27T15:55:30.897 回答
7

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

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

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

于 2021-03-24T07:05:21.350 回答
5

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"

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

于 2020-01-11T15:17:06.390 回答
5

我的部分数据库崩溃时遇到了类似的问题。我所做的是我通过 PHPStorm 数据库控制台更改了数据库中的参数,如下所示:

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

现在像魅力一样工作

于 2020-10-16T17:12:44.373 回答
4

如果您使用的是 PhpMyAdmin,请搜索“SQL 模式”并取消值:ONLY_FULL_GROUP_BY,就可以了。

于 2020-02-03T07:42:23.470 回答
4

两种解决方案:

a) 使用

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

b) 通过使用 ANY_VALUE() 来引用非聚合列,您可以在不禁用 ONLY_FULL_GROUP_BY 的情况下实现相同的效果。

ANY_VALUE(值)

于 2021-12-28T13:36:43.090 回答
3

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

SET SQL_MODE = '';
于 2021-05-02T13:42:27.920 回答
2
  1. 登录到 phpMyAdmin
  2. 导航到:服务器:localhost:3306,不要选择任何数据库
  3. 单击顶部菜单中的变量
  4. 搜索“sql mode”并将对应的值编辑为:NO_ENGINE_SUBSTITUTION

就这样。

我在我的 Ec2 中做到了这一点,它就像魅力一样。

于 2019-06-25T17:59:29.493 回答
2

这是永久设置它的一种非常快速简便的方法

注意:运行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进行更改并重新启动

于 2020-05-05T16:40:40.030 回答
1

您也可以简单地将GROUP_CONCAT()添加到非聚合列。

GROUP_CONCAT(your_column)

于 2021-06-06T14:21:17.970 回答
0

对于本地使用 CentOS/RHEL(Linux 服务器)和 XAMPP 的用户

您好,我找到了一个非常不同的解决方案,希望对您有所帮助。(可能看起来有点矫枉过正,但这确实对我有用,不像其他解决方案)

我正在运行CentOS 7,我的所有代码都在本地运行,但是当我将它上传到我的服务器时,我开始收到这个问题所解决的错误。

几个小时后,我尝试从不同的角度查看问题,我记得我的本地设置使用XAMPP,我以为我使用的是MySQL 8(我的服务器上安装了 MySQL 8)。

但是从 XAMPP 登录到 MySql 后,我得到了下一个输出:

mysql -u root -p //Login


Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 27
Server version: 10.4.18-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

是的,你可能已经注意到了,XAMPP 使用MariaDB,所以解决方案是卸载 mysql 并安装 MariaDB

当我运行 Centos 7 时,执行此操作的步骤如下:

  1. 从您的服务器中删除 mysql

# yum remove mysql mysql-server
  1. 更新您的系统(这在我们每次安装新东西时都很常见)

# sudo yum  -y update
  1. 将 MariaDB 添加到存储库

# sudo tee /etc/yum.repos.d/MariaDB.repo<<EOF 
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
EOF
  1. 更新缓存

# sudo yum makecache fast
  1. 安装 MariaDB

# sudo yum -y install MariaDB-server MariaDB-client
  1. 将 MariaDB 添加到启动中(每次系统重新启动时启动 MariaDB)

#sudo systemctl enable --now mariadb

然后,您可以通过运行以下命令来保护您的安装:

# sudo mysql_secure_installation

最后一个命令将开始一个过程,您可以在其中设置密码和其他选项。

之后不要忘记添加非 root 用户并授予它必要的权限,那是因为您不能在应用程序中使用 root 用户(是的,我必须稍后弄清楚)

首先使用root账户登录:

# mysql -u root -p

然后添加您的用户并授予权限:

CREATE USER 'YourUserName'@localhost IDENTIFIED BY 'YourPassword';
GRANT ALL PRIVILEGES ON *.* TO 'YourUserName'@localhost IDENTIFIED BY 'YourPassword' WITH GRANT OPTION;

最后你必须创建你的数据库,导入你的表/数据/触发器/程序。

现在您将能够像本地设置一样毫无问题地运行您的代码。(也许你必须安装 mysql 扩展,以防你也必须在本地安装)。

于 2021-05-08T05:40:15.197 回答
0

登录到 phpMyAdmin 导航到: 服务器:http://localhost/phpmyadmin 并且不要选择任何数据库 从顶部菜单中单击 SQL 并害虫下面的代码 在服务器上运行 SQL 查询/查询 SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); Sorce 链接

于 2021-06-11T15:48:11.690 回答
0

如果您在 Mac 上使用 MAMP,当您重新启动 MAMP 时,对 MySQL 中变量的任何更改都将被删除。要确保更改是永久性的,请执行以下操作:

停止正在运行的 MAMP 服务器。

使用文本编辑器创建名为 my.cnf 的文件并将其保存到 /Applications/MAMP/conf 文件夹。将文件放在文件夹的根目录(这似乎有点奇怪,因为它包含大量的 apache 文件夹,但没关系)。将以下行添加到文件中:

[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

保存文件并关闭编辑器。启动 MAMP 服务器。

这将使更改永久化。

于 2022-01-06T14:08:53.917 回答
-1

打开 WAMP 面板并打开 MySQL 配置文件。如果您找到它,请在其中搜索“sql_mode”,如果您找不到,请将其设置为“”,否则将 sql_mode="" 添加到文件中。

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

快乐编码。

于 2017-10-05T08:22:57.000 回答
-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

于 2019-06-13T17:04:23.833 回答