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 进行分组可以确保逻辑严谨性。

Original: https://www.cnblogs.com/arvinhuang/p/16437846.html
Author: 平凡键客
Title: MySQL 关于 only_full_group_by 限制

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/620958/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 史上最全面的mysql数据库下载安装教程(适合初学者)

    Original: https://www.cnblogs.com/chaichaichai/p/15330533.htmlAuthor: 牛仔码农Title: 史上最全面的mys…

    数据库 2023年5月24日
    082
  • mysql拆分字符串做条件查询

    mysql拆分字符串作为查询条件 有个群友问一个问题 这表的ancestors列存放的是所有的祖先节点,以 ,分隔 例如我查询dept_id为103的所有祖先节点,现在我只有一个d…

    数据库 2023年5月24日
    069
  • MySQL锁(乐观锁、悲观锁、多粒度锁)

    锁 并发事务可能会发生什么情况: [En] What may happen to concurrent transactions: 读-读事务并发:此时是没有问题的,读操作不会对记…

    数据库 2023年5月24日
    083
  • Mongodb使用总结

    Mongodb使用总结 基于内存操作,便于与网站交互 数据库-集合-文档(存储多种数据类型),我们的操作都是基于单文档进行操作,并且通过冗余字段进行操作 嵌入式数组文档减少了对昂贵…

    数据库 2023年6月11日
    077
  • 分享封装好的异步Mysql动态的库(DyNetMysql.dll) + 项目源码

    在做C++项目时,经常会用到Mysql数据库,Mysql接口提供给我们的数据是相当原始的,如:字段名、字段类型,字段长度等等,一般情况我们都想一种更方便获得数据 如: XXXStr…

    数据库 2023年6月14日
    068
  • MySQL函数学习(四)—–聚合函数

    注:笔记旨在记录 四、MySQL 聚合函数 \ 函 数 名 称 作 用 完 成 1 MAX 求最大值 勾 2 MIN 求最小值 勾 3 COUNT 求数量 勾 4 BIT_COUN…

    数据库 2023年6月16日
    069
  • 类的加载流程

    概述 什么是类加载呢? 我们知道一个Class文件编译完成之后是存在于磁盘的一个普通文件,如果想要执行,必然需要将 Class文件加载到…

    数据库 2023年6月11日
    067
  • Maven的工作机制

    Maven是 Apache 软件基金会组织维护的一款专门为 Java 项目提供 构建和 依赖管理支持的工具。 ·首先, Maven核心程序:负责Maven的总体调度,具体操作使用的…

    数据库 2023年6月16日
    069
  • 集合自序整理集

    集合和数组一样都是对多个数据进行存储操作的容器 * – 集合长度可变,数组长度固定 – 集合可以存储不同数据类型元素,数组只能存储单一数据类型元素 &#82…

    数据库 2023年6月9日
    0107
  • MySQL8.0其他新特性

    MySQL8.0其他新特性 MySQL8.0新特性概述 MySQL8.0新增特性 MySQL8.0移除的旧特性 新特性1:窗口函数 窗口函数的分类 MySQL8.0版本开始支持窗口…

    数据库 2023年5月24日
    069
  • 关于那些我们都听过的营销工具—优惠券

    相信大家对优惠券都不陌生,特别是在现在这个互联网特别发达的时代,优惠券是我们运营推广营销的一种工具,它可以降低产品的价格,是一种常见的消费者营业推广工具, 作为一种信息的载体,它不…

    数据库 2023年6月14日
    069
  • histogram的类型详解

    采样点 每隔指定的时间会采集并上报一次数据,称为采样点。 请注意这里采集的是当前瞬间的数据 count 对采样点的 次数累计和(count) bucket 对采样点的 次数进行统计…

    数据库 2023年6月9日
    0154
  • MySQL 8.0 新特性梳理汇总

    一 历史版本发布回顾 从上图可以看出,基本遵循 5+3+3 模式 5—GA发布后,5年 就停止通用常规的更新了(功能不再更新了); 3—企业版的,+3年功能…

    数据库 2023年6月16日
    076
  • CentOS7源码安装Python、virtualenv虚拟环境安装、uwsgi安装配置

    一:Python源码安装 1:Python源码下载XZ开头的 https://www.python.org/downloads/source/ 2:解压:tar xf Python…

    数据库 2023年6月6日
    0100
  • SQL语句实战学习

    参考:https://zhuanlan.zhihu.com/p/38354000再次感谢作者的整理!! 1.数据已提前准备好了,已知有如下4张表:学生表:student 成绩表:s…

    数据库 2023年6月16日
    075
  • MySQL实战45讲 3

    03 | 事务隔离:为什么你改了我还看不见? 事务 Transaction TRX 事务就是 要保证一组数据库操作,要么全部成功,要么全部失败。 MySQL 原生的 MyISAM …

    数据库 2023年5月24日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球