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

SELECT list is not in GROUP BY clause and contains nonaggregated column .... incompatible with sql_mode=only_full_group_by

AM 在我的 windows PC 上使用 MySQL 5.7.13 和 WAMP 服务器

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

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

我总是遇到这样的错误

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'returntr_prod.tbl_customer_pod_uploads.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with 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 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+

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

  • proof_type 列,或
  • 任何其他列的聚合


其他列的 "aggregates" 是指对另一列使用聚合函数,例如 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 上看到的绝大多数 MySQL GROUP BY 问题都关闭了严格模式,因此查询是 运行ning,但结果不正确。在你的情况下,查询根本不会 运行,迫使你考虑你真正想做什么。

注意:ANSI SQL 扩展了 select 在 GROUP BY 中允许编辑的内容,还包括 功能相关的列 在正在 selected 的列上。函数依赖的一个例子是按 table 中的主键列分组。由于保证每条记录的主键都是唯一的,因此也可以确定任何其他列的值。 MySQL 是允许这样做的数据库之一(SQL 服务器和 Oracle 不支持 AFAIK)。

这个

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'returntr_prod.tbl_customer_pod_uploads.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with 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

OR 只需将所有列包含在 SELECT 语句指定的 GROUP BY 子句中。 sql_mode 可以保持启用状态。

谢谢...:-)

您可以禁用 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';

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

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

编码愉快。

For the query to be legal in SQL92, the name column must be omitted from the select list or named in the GROUP BY clause.

SQL99 and later permits such nonaggregates per optional feature T301 if they are functionally dependent on GROUP BY columns: If such a relationship exists between name and custid, the query is legal. This would be the case, for example, were custid a primary key of customers.

MySQL 5.7.5 and up implements detection of functional dependence. If the ONLY_FULL_GROUP_BY SQL mode is enabled (which it is by default), MySQL rejects 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 them.

via MySQL :: MySQL 5.7 Reference Manual :: 12.19.3 MySQL Handling of GROUP BY

你可以通过以下命令改变sql模式来解决它:

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

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

从外观上看,我认为按多个 columns/fields 分组不会影响您的结果。为什么不试试这样加群:

GROUP BY `proof_type`, `id`

这将首先按 proof_type 分组,然后 id。我希望这不会改变结果。在 some/most 个案例中,按多列分组给出了错误的结果。

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

自Mysql版本5.7.5ONLY_FULL_GROUP_BY默认启用SQL模式

5.7.5 之前的版本: ONLY_FULL_GROUP_BY 默认未启用。

如果启用 ONLY_FULL_GROUP_BY SQL 模式(从 5.7.5 版开始默认启用),MySQL 拒绝 select 列表的查询, HAVING 条件或 ORDER BY 列表指的是既未在 GROUP BY 子句中命名也不在功能上依赖于它们的非聚合列。

要解决问题,请使用以下 3 种解决方案中的任意一种

(1) PHPMyAdmin

禁用ONLY_FULL_GROUP_BY模式

如果您使用的是 phpMyAdmin,则更改 sql_mode 设置,如下面的屏幕截图所示。

编辑 sql mode 变量并从值

中删除 ONLY_FULL_GROUP_BY 文本

(2)SQL/Command提示

禁用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 等)


重要提示

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

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

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

变量名: sql_mode OR sql-mode

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

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

[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

在你的 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

  1. 登录 phpMyAdmin
  2. 导航至:服务器:localhost:3306 并执行 不是 select 任何数据库
  3. 点击顶部菜单中的变量
  4. 搜索 "sql mode" 并将相应的值编辑为:NO_ENGINE_SUBSTITUTION

就这些了。

我在我的 Ec2 中做到了这一点,效果非常好。

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

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

更新 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 中创建一个新文件,然后添加以上行。

在Ubuntu

第 1 步:

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

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

sql_mode = ""

第 3 步:保存

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

您好,不要获取所有列,只需使用 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`

如果您使用的是 PhpMyAdmin,请搜索 "SQL mode" 并取下值:ONLY_FULL_GROUP_BY,就这样做了,没问题。

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

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
> sudo nano /etc/mysql/my.cnf

在下面输入

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart

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

注意:运行ning 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. 通过 运行ning chmod +x disable-strict-mode.sh
  4. 使脚本可执行
  5. 运行 运行ning ./disable-strict-mode.sh
  6. 的脚本

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

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

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

现在很有魅力

only_full_group_by = on 告诉 MySQL 引擎:当您对要显示的结果有疑问时不要应用 GROUP BY 并抛出一个错误。 只有Group By明确告诉您该做什么时才应用它。即,当 Group By 已满且完美时!

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

只要使用得当GROUP BY就不用关掉!

示例:

Table:用户

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

当您在 name 列上使用 GROUP BY 时:

SELECT * FROM users GROUP BY name;

有两种可能的结果:

  1      ali
  2      john     

  2      john
  3      ali

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

解决方案1:

仅选择 name 字段:

SELECT name FROM users GROUP BY name;

结果:

  ali
  john     

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

解决方案2:

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

解决方案3

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

例如:

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

结果:

  2      john     
  3      ali

它会选择 ali 行最大 id

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

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

因为我使用的是存储过程。执行此查询后,我不得不 删除过程并重新创建

之前运行宁你查询运行以下查询

SET SQL_MODE = '';

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

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

我正在 运行ning 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;

最后你必须创建你的数据库,导入你的tables/data/triggers/procedures。

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

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

喜欢GROUP_CONCAT(your_column)

登录到 phpMyAdmin 导航至:服务器:http://localhost/phpmyadmin 并且不要 select 任何数据库 单击顶部菜单中的 SQL,然后在服务器上的代码 运行 SQL query/queries 下方安装 SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); Sorce link

两种解决方案:

a) 使用

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

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

ANY_VALUE(value)

如果您在 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 服务器。

这将使更改永久化。

就我而言,这是我的旧 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"

你可以用

检查sql_mode
show variables like "sql_mode";

然后我设置成这样

SET sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';