MySQL 关于 only_full_group_by 限制「终于解决」

MySQL 关于 only_full_group_by 限制「终于解决」先上结论 如果 only_full_group_by 被启用,那么在查询时,如果某个列不在group by 列表中,此时如果不对该列进行聚合处理,则该列不能出现在 select 列表,having 条

MySQL 关于 only_full_group_by 限制

先上结论

如果 only_full_group_by 被启用,那么在查询时,如果某个列不在group by 列表中,此时如果不对该列进行聚合处理,则该列不能出现在 select 列表,having 条件中及order by 列表中

MySQL 8.0 默认启用了sql_mode,我们可以通过 select @@session.sql_mode 查看会话中的 sql_mode 配置。

mysql> SELECT @@session.sql_mode;
+-----------------------------------------------------------------------------------------------------------------------+
| @@session.sql_mode
|
+-----------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

有这么一张表

CREATE TABLE `mytable`
(
    `id` int unsigned NOT NULL,
    `a`  varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL,
    `b`  int                                    DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci;

INSERT INTO mytable
VALUES (1, "abc", 1000),
       (2, "abc", 2000),
       (3, "def", 4000);

当我们执行的 SQL 语句包含聚合函数时,MYSQL 提示需要使用 GROUP BY 进行分组。

mysql> SELECT a,SUM(b) FROM mytable;
ERROR 1140 (42000): In aggregated query without GROUP BY, 
expression #1 of SELECT list contains nonaggregated column "study.mytable.a"; 
this is incompatible with sql_mode=only_full_group_by
如果我们关掉 only_full_group_by 限制,SQL 语句就正常执行了,但又没有完全正常执行。

mysql> SET sql_mode = "";
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT a,SUM(b) FROM mytable;
+------+--------+
| a    | SUM(b) |
+------+--------+
| abc  |   7000 |
+------+--------+
1 row in set (0.00 sec)

可以看到,虽然我们得到了 SUM(b) 的值为 7000 是期望的,但是 a 的值为 abc 不是我们期望的。

MySQL 8.0 里的文档提到这么一句话

the query is processed by treating all rows as a single group, but the value selected for each named column is nondeterministic
在这个例子中,a 的值就是不确定的

当 WHERE 过滤条件中包含了 SELECT 列表中全部非聚合列的字段,则在开启 only_full_group_by 下也可以正常工作

In this case, every such column must be limited to a single value in theWHEREclause, and all such limiting conditions must be joined by logicalAND
mysql> SET SESSION sql_mode = sys.list_add(@@session.sql_mode, "ONLY_FULL_GROUP_BY");
Query OK, 0 rows affected (0.01 sec)


mysql> SELECT a,SUM(b) FROM mytable;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column "study.mytable.a"; this is incompatible with sql_mode=only_full_group_by
mysql> SELECT a, SUM(b) FROM mytable WHERE a = "abc";
+------+--------+
| a    | SUM(b) |
+------+--------+
| abc  |   3000 |
+------+--------+
1 row in set (0.00 sec)

mysql> SELECT * FROM mytable1;
+----+------+------+-------+
| id | a    | b    | c     |
+----+------+------+-------+
|  1 | abc  | qrs  |  1000 |
|  2 | abc  | tuv  |  2000 |
|  3 | def  | qrs  |  4000 |
|  4 | def  | tuv  |  8000 |
|  5 | abc  | qrs  | 16000 |
|  6 | def  | tuv  | 32000 |
+----+------+------+-------+
6 rows in set (0.00 sec)

mysql> SELECT a, b, SUM(c) FROM mytable1 WHERE a = "abc" OR b = "qrs";
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column "study.mytable1.a"; this is incompatible with sql_mode=only_full_group_by
mysql> SELECT a, b, SUM(c) FROM mytable1 WHERE a = "abc" AND b = "qrs";
+------+------+--------+
| a    | b    | SUM(c) |
+------+------+--------+
| abc  | qrs  |  17000 |
+------+------+--------+
1 row in set (0.00 sec)

这种方式可以理解为通过条件限制确定了分组条件。因为没有指名分组时,MySQL 将所有字段视为一个组处理。

在开启 only_full_group_by 限制时,也可以通过 ANY_VALUE 函数,使MySQL 正常执行语句,显而易见的是,我们得到的值是不确切的。

mysql> SELECT a,SUM(b) FROM mytable;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column "study.mytable.a"; this is incompatible with sql_mode=only_full_group_by
mysql> SELECT ANY_VALUE(a),SUM(b) FROM mytable;
+--------------+--------+
| ANY_VALUE(a) | SUM(b) |
+--------------+--------+
| abc          |   7000 |
+--------------+--------+
1 row in set (0.00 sec)

综上,在使用聚合函数的场景中,使用 GROUP BY 进行分组可以确保逻辑严谨性。

推荐阅读:
https://dev.mysql.com/doc/refman/8.0/en/counting-rows.html
https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html

原文地址:https://www.cnblogs.com/arvinhuang/archive/2022/07/02/16437846.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/5062.html

(0)
上一篇 2023-05-25 09:30
下一篇 2023-05-25

相关推荐

  • Redis持久化存储(AOF与RDB)「终于解决」

    Redis持久化存储(AOF与RDB)「终于解决」[TOC] 该部分其实在redis常用语法及设置里面有介绍 要看详细的话, 可以看这里 Redis持久化存储 一部分转自: https://blog.csdn.net/canot/article/d…

    2023-02-03
    151
  • SQL Server 中的异常处理「建议收藏」

    SQL Server 中的异常处理「建议收藏」为什么我们需要 SQL Server 中的异常处理? 让我们通过一个示例来了解 SQL Server 中异常处理的必要性。因此,创建一个 SQL Server 存储过程,通过执行以下查询来除以两个数字

    2023-05-26
    154
  • sparksql 概述「终于解决」

    sparksql 概述「终于解决」什么是Spark SQL? Spark SQL是Spark用来处理结构化数据的一个模块,它提供了2个编程抽象:DataFrame和DataSet,并且作为分布式SQL查询引擎的作用。 我们已经学习了H

    2023-02-04
    159
  • 管理服务器价格_r6连不上服务器

    管理服务器价格_r6连不上服务器Laxcus管理几十万台服务器,是怎么做到的?这是来自头条网友提问,贴到博客园,希望对大家了解LAXCUS集群操作系统有点帮助。

    2023-04-14
    152
  • Python模块:Pandas数据处理与分析

    Python模块:Pandas数据处理与分析Pandas是一个数据处理和分析的Python库,在数据的清洗、整理、处理、分析等方面提供了很多功能,使得数据分析变得更加高效、简便。它的核心是两个数据结构:Series和DataFrame。Series是一种一维数组,可以用来存储一些列标签或一些应用标签的数据,而DataFrame则是二维结构,类似于表格,可以存储多种类型的数据。Pandas是基于Numpy框架建立的,可以很好地与其它科学计算库协作使用。

    2024-03-27
    79
  • Python如何运行程序

    Python如何运行程序Python是一种解释性语言,这意味着每行代码都是逐行解释运行的。Python解释器可以直接把源代码转换为字节码并执行,这极大地提高了程序开发的效率。Python也可以使用编译器将源代码编译成字节码文件,这样可以避免每次都重新解释代码,提高性能。

    2024-09-14
    27
  • 面向过程式的数据库连接「终于解决」

    面向过程式的数据库连接「终于解决」1、mysql系列函数 –连接mysql的老函数,性能不佳,已经被mysqli替代 2、mysqli系列函数 –mysql系列的增强版,如果直接连接mysql数据库,性能最好 3、pdo抽象层 …

    2023-02-10
    140
  • 安装pyspider

    安装pyspider

    2024-06-04
    58

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注