Mysql升级到5.7后遇到的group by查询问题解决

yizhihongxing

当将MySQL数据库升级到5.7版本后,可能会出现一些与group by查询相关的问题,这是因为MySQL 5.7的group by语句在某些情况下会产生与之前版本不同的结果。

为了解决这些问题,可以采用以下步骤:

1.启用SQL_MODE

MySQL 5.7具有更严格的SQL_MODE,以提高数据的一致性和准确性。可以通过修改/etc/mysql/mysql.conf.d/mysql.cnf文件(具体路径可能会有所不同)以启用SQL_MODE。

在文件的[mysqld]部分添加如下行(如果已有其他SQL_MODE,请在末尾添加):

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服务以使更改生效。

2.使用ONLY_FULL_GROUP_BY选项进行group by查询

MySQL 5.7的group by语句默认启用ONLY_FULL_GROUP_BY选项,这意味着在进行group by查询时,查询的列必须要出现在SELECT语句中,否则会产生错误。可以使用以下语句关闭ONLY_FULL_GROUP_BY选项:

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

可以将以上命令添加到连接数据库之前的脚本中,以确保每次连接时都会关闭ONLY_FULL_GROUP_BY选项。

示例1:group by查询中的错误

假设我们有以下两个表:

CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_id INT,
  total INT
);

CREATE TABLE customers (
  id INT PRIMARY KEY,
  name VARCHAR(50),
  age INT
);

orders表中存储了每个客户的订单信息,customers表中存储了客户的基本信息。现在我们想获取每个客户的名字和订单的平均总价。可以使用以下查询语句:

SELECT 
  customers.name, 
  AVG(orders.total) 
FROM 
  orders 
  INNER JOIN customers 
    ON orders.customer_id = customers.id 
GROUP BY 
  customers.id;

在MySQL 5.6及更早版本中,以上查询是有效的,可以返回正确的结果。但是,在MySQL 5.7中,执行以上查询会产生以下错误:

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.customers.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

这是因为MySQL 5.7默认启用了ONLY_FULL_GROUP_BY选项,查询语句中的customers.name列未在GROUP BY语句中出现。修复该错误的方法是将customers.name列添加到GROUP BY语句中:

SELECT 
  customers.name, 
  AVG(orders.total) 
FROM 
  orders 
  INNER JOIN customers 
    ON orders.customer_id = customers.id 
GROUP BY 
  customers.id, 
  customers.name;

示例2:使用ONLY_FULL_GROUP_BY选项进行group by查询

现在我们想获取每个客户的名字和订单的平均总价,但是只想返回有订单的客户。可以使用以下查询语句:

SELECT 
  customers.name, 
  AVG(orders.total) 
FROM 
  orders 
  RIGHT JOIN customers 
    ON orders.customer_id = customers.id 
GROUP BY 
  customers.id 
HAVING 
  COUNT(orders.total) > 0;

在MySQL 5.6及更早版本中,以上查询是有效的,可以返回正确的结果(对于没有订单的客户,AVG(orders.total)返回NULL)。但是,在MySQL 5.7中,执行以上查询会产生以下错误:

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.customers.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

这是因为查询语句中使用了RIGHT JOIN,有些客户可能没有订单,AVG(orders.total)会返回NULL。为了修复该错误,可以使用以下查询语句:

SELECT 
  customers.name, 
  AVG(IFNULL(orders.total, 0)) 
FROM 
  orders 
  RIGHT JOIN customers 
    ON orders.customer_id = customers.id 
GROUP BY 
  customers.id 
HAVING 
  COUNT(IFNULL(orders.total, 0)) > 0;

以上查询使用了IFNULL函数将NULL值替换为0,从而使AVG函数返回正确的值。同时,在COUNT函数中也使用了IFNULL函数,以便正确计算客户的订单数。

通过以上步骤和示例,我们可以正确地使用MySQL 5.7进行group by查询。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Mysql升级到5.7后遇到的group by查询问题解决 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • mysql中TINYINT取值范围是多少

    这篇文章主要介绍了mysql中TINYINT取值范围是多少的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mysql中TINYINT取值范围是多少文章都会有所收获,下面我们一起来看看吧。 项目场景: 最近在开发过程中,看见表设计中是thinyint字段,但对于它的范围产生了好奇 问题描述: 当我们填写超过128数值的时候,该字段就…

    2023年4月9日
    00
  • MySQL 8.0中InnoDB buffer pool size进度更透明

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。 作者:Yejinrong/叶金荣 文章来源:GreatSQL社区原创 MySQL 8.0 up up up~ 从MySQL 5.7开始,支持在线动态调整 innodb buffer pool,并为此新增了一个状态…

    MySQL 2023年5月4日
    00
  • 查询mysql中执行效率低的sql语句的方法

    查询MySQL中执行效率低的SQL语句是一项非常重要的任务,可以帮助我们优化数据库的性能,提升网站的访问速度。下面我来详细讲解一下查询方法的完整攻略。 步骤一:开启慢查询日志 开启慢查询日志是查询MySQL中执行效率低的SQL语句的第一步。在MySQL的配置文件中,找到my.cnf或my.ini文件,将以下配置项添加到文件中: slow_query_log …

    MySQL 2023年5月19日
    00
  • MySQL修改数据库(ALTER DATABASE语句)

    MySQL中修改数据库的语句是ALTER DATABASE,它允许用户更改数据库的名称和字符集。下面,我们将深入解析ALTER DATABASE的使用方法。 修改数据库名称 要修改数据库的名称,可以使用以下语法: ALTER DATABASE old_db_name RENAME TO new_db_name; 其中,“old_db_name”是要更改名称的…

    MySQL 2023年3月9日
    00
  • Navicat数据存放位置和备份数据库路径设置方式

    Navicat是一款常用的数据库管理工具,用户可以通过Navicat对数据库进行访问、管理和备份等操作。在使用Navicat过程中,为确保数据的安全性,需要设置数据存放位置和备份数据库路径。下面就详细讲解Navicat数据存放位置和备份数据库路径的设置方式。 设置数据存放位置 步骤一:打开Navicat 首先需要打开Navicat,进入主界面。 步骤二:选择…

    MySQL 2023年5月18日
    00
  • 解决Navicat for MySQL 连接 MySQL 报2005错误的问题

    解决 Navicat for MySQL 连接 MySQL 报2005错误的问题 问题描述 在使用 Navicat for MySQL 连接 MySQL 数据库时,可能会遇到 “2005 – Unknown MySQL server host” 错误,错误信息如下: 2005 – Unknown MySQL server host ‘hostname’ (0…

    MySQL 2023年5月18日
    00
  • MySQL索引可以分为哪些类型?

    MySQL索引可分为以下几类: B-Tree索引:最常见的索引类型,适用于全值匹配、范围查询和排序等操作。 Hash索引:适用于只有等值操作,不能进行范围查询和排序等操作。 Full-Text索引:适用于对文本进行全文搜索,可以在大型数据集中快速找到相关的文本。 Spatial索引:适用于地理数据类型,支持空间查询和空间索引。 Clustered索引:在My…

    MySQL 2023年3月10日
    00
  • <经验杂谈>Mysql中字符串处理的几种处理方法concat、concat_ws、group_concat

    Mysql中字符串处理的几种处理方法concat、concat_ws、group_concat以下详情: MySQL中concat函数使用方法:CONCAT(str1,str2,…)   返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。 注意:如果所有参数均为非二进制字符串,则结果为非二进制字符串。 如果自变量中含有任一二…

    MySQL 2023年4月13日
    00
合作推广
合作推广
分享本页
返回顶部