解决MySQL 5.7.9版本sql_mode=only_full_group_by问题

当MySQL的版本为5.7.9及以上时,启动sql_mode为only_full_group_by时,可能会导致部分SQL语句执行异常。本攻略将会介绍如何解决这个问题。

问题描述

在MySQL 5.7.9及以上版本中,启动sql_mode为only_full_group_by时,如果有GROUP BY的SQL语句中包含非GROUP BY中的字段,MySQL会抛出如下异常。

ERROR 1055 (42000): Expression #N of SELECT list is not in GROUP BY clause and contains nonaggregated column ...

解决方法

1. 修改MySQL配置文件

可以直接修改MySQL的配置文件,去掉only_full_group_by模式。

  1. 找到MySQL的配置文件my.cnf或者my.ini,这个文件默认在MySQL的安装目录的etc目录下。
  2. 找到[mysqld]标签所在的位置,增加如下配置。
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
  1. 重启MySQL服务以生效。

2. 修改SQL语句

可以在SQL语句中进行调整,使其符合only_full_group_by模式中规定的限制条件。

正确的方式是确保GROUP BY子句包含了所有查询选择列表中的非聚合列,并不是所有的非聚合列都需要包含在GROUP BY子句里面。如果我们只想要非聚合列的唯一值,而不在意它们的值,那么可以使用聚合函数。

例如,原本的SQL语句是这样的:

SELECT col1, col2, col3
FROM tbl
WHERE some_col='some_val'
GROUP BY col1

only_full_group_by模式下,这条SQL语句会失败。我们可以调整SQL语句,使用MAX()函数或者MIN()函数,将GROUP BY子句中缺少的非聚合列从SELECT子句中删除并用聚合函数代替。

SELECT col1, MAX(col2), MAX(col3)
FROM tbl
WHERE some_col='some_val'
GROUP BY col1

如果需要全部保留非聚合列,则可以使用内联子查询或者临时表。

举例:

SELECT t1.*, t2.*
FROM (
    SELECT col1
    FROM tbl
    WHERE some_col='some_val'
    GROUP BY col1
) AS t1
JOIN tbl AS t2 ON t1.col1=t2.col1

示例说明

示例1

假设有这样一张表格t_student,其中包含学生ID、所属省份和所属城市三列数据。

CREATE TABLE t_student (
    id INT PRIMARY KEY,
    province VARCHAR(255) NOT NULL,
    city VARCHAR(255) NOT NULL
);

INSERT INTO t_student VALUES(1, 'Shandong', 'Jinan');
INSERT INTO t_student VALUES(2, 'Shandong', 'Qingdao');
INSERT INTO t_student VALUES(3, 'Jiangsu', 'Nanjing');
INSERT INTO t_student VALUES(4, 'Jiangsu', 'Suzhou');

如果我们想要获取每个省份中的任意一个城市,则可以使用如下的SQL语句:

SELECT id, province, city
FROM t_student
GROUP BY province;

在MySQL 5.7.9及以上的版本中,启用only_full_group_by时,会抛出如下异常:

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

为了解决这个问题,我们可在my.cnf或者my.ini中去掉only_full_group_by模式,或者修改SQL语句。具体来说,我们可以使用MAX()函数或者MIN()函数,将GROUP BY子句中缺少的非聚合列从SELECT子句中删除并用聚合函数代替。

-- 修改后的SQL语句
SELECT province, MAX(city)
FROM t_student
GROUP BY province;

示例2

假设有这样一张表格t_result,其中包含学生ID、考试类型和成绩三列数据。

CREATE TABLE t_result (
    id INT NOT NULL,
    type VARCHAR(255) NOT NULL,
    score FLOAT NOT NULL
);

INSERT INTO t_result VALUES (1, 'Math', 90);
INSERT INTO t_result VALUES (2, 'Math', 80);
INSERT INTO t_result VALUES (3, 'Chinese', 95);
INSERT INTO t_result VALUES (4, 'Chinese', 85);

如果我们想要获取每种考试类型中的最高分,则可以使用如下的SQL语句:

SELECT type, id, MAX(score)
FROM t_result
GROUP BY type;

在MySQL 5.7.9及以上的版本中,启用only_full_group_by时,会抛出如下异常:

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

为了解决这个问题,我们可在my.cnf或者my.ini中去掉only_full_group_by模式,或者修改SQL语句。具体来说,我们可以将缺少的非聚合列使用内联子查询或者临时表来获取。

-- 修改后的SQL语句,使用内联子查询
SELECT t1.type, t1.id, t1.score
FROM t_result t1
INNER JOIN (
    SELECT type, MAX(score) AS score
    FROM t_result
    GROUP BY type
) t2 ON t1.type=t2.type AND t1.score=t2.score;
-- 修改后的SQL语句,使用临时表
CREATE TEMPORARY TABLE t_max_score
    SELECT type, MAX(score) AS score
    FROM t_result
    GROUP BY type;

SELECT t1.type, t1.id, t1.score
FROM t_result t1
INNER JOIN t_max_score t2 ON t1.type=t2.type AND t1.score=t2.score;

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解决MySQL 5.7.9版本sql_mode=only_full_group_by问题 - Python技术站

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

相关文章

  • mysql+proxysql+replication-manager的主从半同步复制+高可用+读写分离

    环境: AlmaLinux release 9.1 MySQL Community Server Ver 8.0.33 Replication Manager v2.2.40 for MariaDB 10.x and MySQL 5.7 Series ProxySQL version 2.5.1-90-gbedaa6c 主机分配情况: 采用hyper-v创建…

    MySQL 2023年4月23日
    00
  • my.cnf(my.ini)重要参数优化配置说明

    首先,说明一下my.cnf(my.ini)是什么: my.cnf(my.ini)是MySQL的配置文件,存放在MySQL的安装目录下,用于配置MySQL的各种参数。 下面是my.cnf的重要参数优化配置说明: 1.缓冲池配置 缓冲池是MySQL的内存池,用来缓冲MySQL的数据和索引。以下是常用缓冲池参数的配置,可以根据实际情况进行调整: # InnoDB缓…

    MySQL 2023年5月19日
    00
  • mysql启动失败之mysql服务无法启动(服务没有报告任何错误)的解决方法

    当MySQL服务无法启动时,系统没有报告任何错误,这可能是由于多种原因导致的。以下是可能出现这种情况并可能导致服务无法启动的一些原因: MySQL配置文件中的错误 MySQL数据文件已损坏或与MySQL服务不兼容 MySQL服务端口被其他应用占用 下面是解决方法的攻略,以及两个具体的示例: 确认配置文件中的错误 首先,检查MySQL的配置文件my.cnf是否…

    MySQL 2023年5月18日
    00
  • Windows下MySQL 5.7无法启动的解决方法

    Windows下MySQL 5.7无法启动的解决方法 问题描述 在Windows操作系统上,当尝试启动MySQL 5.7 时,可能会遇到无法启动的情况。这个问题可能由多种原因引起,如端口占用、配置文件错误、权限问题等。本篇攻略将分别介绍解决这些问题的方法,以帮助读者快速解决问题,并顺利启动MySQL 5.7。 解决方法一:检查端口占用以及防火墙设置 打开cm…

    MySQL 2023年5月18日
    00
  • 详解MySQL日期和时间类型的使用方法

    MySQL支持多种日期和时间类型,每种类型都适用于不同的情境。下面是MySQL支持的日期和时间类型: DATE:日期类型,格式为YYYY-MM-DD。它用于存储日期信息,例如出生日期、应收账单日期等。 TIME:时间类型,格式为HH:MM:SS。它用于存储时刻信息,例如开门时间、开机时间等。 DATETIME:日期时间类型,格式为YYYY-MM-DD HH:…

    MySQL 2023年3月9日
    00
  • MySQL命令行登入的方式有哪些

    这篇“MySQL命令行登入的方式有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL命令行登入的方式有哪些”文章吧。 方法一: 开始菜单 -> 所有程序 -> MySQL -> MySQL Server 8.0 -&…

    MySQL 2023年4月14日
    00
  • 在mac上如何使用终端打开XAMPP自带的MySQL

    以下是在Mac上使用终端打开XAMPP自带的MySQL的完整攻略: 步骤一:打开终端 在Mac上打开终端的快捷键可以是 “Command + 空格”,然后输入 “Terminal”,回车即可。 步骤二:进入XAMPP的安装目录 在终端中输入以下命令,打开XAMPP的安装目录: cd /Applications/XAMPP 步骤三:启动MySQL 在终端中,输…

    MySQL 2023年5月18日
    00
  • 详解MySQL使用GROUP BY分组查询

    MySQL中GROUP BY语句用于将数据行按照一个或多个列进行分组,然后对每个组进行聚合计算。在GROUP BY语句中,可以使用聚合函数对每个组进行计算,例如SUM、AVG、MAX、MIN、COUNT等。 以下是GROUP BY语句的一般语法: SELECT column1, column2, …, aggregate_function(column_…

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