MySQL中GROUP BY隐式排序是什么概念呢? 主要是其它RDBMS没有这样的概念,如果没有认真了解过概念,对这个概念会感觉有点困惑,我们先来看看官方文档的介绍:

官方文档MySQL 5.7 Reference Manual中的“.2.1.14 ORDER BY Optimization”章节有如下介绍:

GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators for GROUP BY columns). However, relying on implicit GROUP BY sorting (that is, sorting in the absence of ASC or DESC designators) or explicit sorting for GROUP BY (that is, by using explicit ASC or DESC designators for GROUP BY columns) is deprecated. To produce a given sort order, provide an ORDER BY clause.

默认情况下GROUP BY隐式排序(即,缺少GROUP BY列的ASC或DESC指示符)。但是,不推荐依赖于隐式GROUP BY排序(即,在没有ASC或DESC指示符的情况下排序)或GROUP BY的显式排序(即,通过对GROUP BY列使用显式ASC或DESC指示符)。要生成给定的排序 ORDER,请提供ORDER BY子句。

从MySQL 8.0开始,GROUP BY字段不再支持隐式排序. 官方文档MySQL 8.0 Reference Manual中“8.2.1.16 ORDER BY Optimization”章节有如下介绍:

Previously (MySQL 5.7 and lower), GROUP BY sorted implicitly under certain conditions. In MySQL 8.0, that no longer occurs, so specifying ORDER BY NULL at the end to suppress implicit sorting (as was done previously) is no longer necessary. However, query results may differ from previous MySQL versions. To produce a given sort order, provide an ORDER BY clause.

那么来看看MySQL的GROUP BY隐式排序(GROUP BY sorted implicitly)吧。我们用“Removal of implicit and explicit sorting for GROUP BY”这篇博客中的例子。

下面实验环境为MySQL 5.6.41()

  1. mysql> select version() from dual;

  1. +------------+

  1. | version()  |

  1. +------------+

  1. | 5.6.41-log |

  1. +------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> CREATE TABLE t (id INTEGER,  cnt INTEGER);

  1. Query OK, 0 rows affected (0.04 sec)

  1.  

  1. mysql> INSERT INTO t VALUES (4,1),(3,2),(1,4),(2,2),(1,1),(1,5),(2,6),(2,1),(1,3),(3,4),(4,5),(3,6);

  1. Query OK, 12 rows affected (0.00 sec)

  1. Records: 12  Duplicates: 0  Warnings: 0

#MySQL在这里隐式地对GROUP BY的结果进行排序(即在缺少GROUP BY列的ASC或DESC指示符的情况下)。

  1. mysql> SELECT id, SUM(cnt) FROM t GROUP BY id; --GROUP BY隐式排序

  1. +------+----------+

  1. | id   | SUM(cnt) |

  1. +------+----------+

  1. |    1 |       13 |

  1. |    2 |        9 |

  1. |    3 |       12 |

  1. |    4 |        6 |

  1. +------+----------+

  1. 4 rows in set (0.00 sec)

MySQL还支持使用GROUP BY进行显式排序(即通过对GROUP BY列使用显式ASC或DESC指示符)

  1. mysql> SELECT id, SUM(cnt) FROM t GROUP BY id DESC;  --GROUP BY显式排序

  1. +------+----------+

  1. | id   | SUM(cnt) |

  1. +------+----------+

  1. |    4 |        6 |

  1. |    3 |       12 |

  1. |    2 |        9 |

  1. |    1 |       13 |

  1. +------+----------+

  1. 4 rows in set (0.00 sec)

从MySQL8.0开始,MySQL不再支持GROUP BY的隐式或显示排序,如下所示:

#下面实验环境为MySQL 8.0.18

  1. mysql> select version();

  1. +-----------+

  1. | version() |

  1. +-----------+

  1. | 8.0.18    |

  1. +-----------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> CREATE TABLE t (id INTEGER,  cnt INTEGER);

  1. Query OK, 0 rows affected (0.39 sec)

  1.  

  1. mysql> INSERT INTO t VALUES (4,1),(3,2),(1,4),(2,2),(1,1),(1,5),(2,6),(2,1),(1,3),(3,4),(4,5),(3,6);

  1. Query OK, 12 rows affected (0.10 sec)

  1. Records: 12  Duplicates: 0  Warnings: 0

  1.  

  1. mysql> SELECT id, SUM(cnt) FROM t GROUP BY id;

  1. +------+----------+

  1. | id   | SUM(cnt) |

  1. +------+----------+

  1. |    4 |        6 |

  1. |    3 |       12 |

  1. |    1 |       13 |

  1. |    2 |        9 |

  1. +------+----------+

  1. 4 rows in set (0.00 sec)

  1.  

  1. mysql> SELECT id, SUM(cnt) FROM t GROUP BY id DESC;

  1. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DESC' at line 1

如上所示,GROUP BY隐式排序不支持了,在MySQL 8.0中,上面测试例子是无序的。GROUP BY显示排序则直接报错。所以如果有数据库从MySQL 5.7或之前的版本,迁移升级到MySQL 8的话,就需要特别留意这个问题了。正确的做法应该是GROUP BY .. ORDER BY 这种操作。如下所示:

  1. mysql>  SELECT id, SUM(cnt) FROM t GROUP BY id

  1.     ->  ORDER BY id;

  1. +------+----------+

  1. | id   | SUM(cnt) |

  1. +------+----------+

  1. |    1 |       13 |

  1. |    2 |        9 |

  1. |    3 |       12 |

  1. |    4 |        6 |

  1. +------+----------+

  1. 4 rows in set (0.00 sec)

  1.  

  1. mysql>

MySQL 8.0.13中删除了GROUP BY的显式排序。至于为什么MySQL 8.0不再支持GROUP BY的隐式排序和显示排序,这篇文章“Removal of implicit and explicit sorting for GROUP BY”已经有详细的介绍,这里不画蛇添足了。

参考资料:

https://mysqlserverteam.com/removal-of-implicit-and-explicit-sorting-for-group-by/

MySQL解惑——GROUP BY隐式排序的更多相关文章

  1. MySQL解惑——GROUP BY隐式排序

    原文:MySQL解惑--GROUP BY隐式排序 MySQL中GROUP BY隐式排序是什么概念呢? 主要是其它RDBMS没有这样的概念,如果没有认真了解过概念,对这个概念会感觉有点困惑,我们先来看看 ...

  2. mysql的几种隐式转化

    1. 表定义是字符型,传入的是Int 2. 字符集不一致.表定义的字段是gbk,传入的是utf8:这种在存储过程中出现得比较多. 数据库的字符集utf8 mysql> show create d ...

  3. MySQL索引失效之隐式转换

    常见索引失效: 1. 条件索引字段"不干净":函数操作.运算操作 2. 隐式类型转换:字符串转数值:其他类型转换 3. 隐式字符编码转换:按字符编码数据长度大的方向转换,避免数据截 ...

  4. MySQL隐式转化整理

    MySQL隐式转化整理 前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下.希望对大家有所帮 ...

  5. mysql的隐式转化

    MySQL隐式转化整理 前几天在微博上看到一篇文章:价值百万的 MySQL 的隐式类型转换感觉写的很不错,再加上自己之前也对MySQL的隐式转化这边并不是很清楚,所以就顺势整理了一下.希望对大家有所帮 ...

  6. MySQL的隐式类型转换整理总结

    当我们对不同类型的值进行比较的时候,为了使得这些数值「可比较」(也可以称为类型的兼容性),MySQL会做一些隐式转化(Implicit type conversion). 比如下面的例子:   1 2 ...

  7. MySQL SQL优化之字符串索引隐式转换

    之前有用户很不解:SQL语句非常简单,就是select * from test_1 where user_id=1 这种类型,而且user_id上已经建立索引了,怎么还是查询很慢? test_1的表结 ...

  8. Mysql隐式类型转换原则

    MySQL 的隐式类型转换原则: - 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换 ...

  9. MYSQL中默认隐式事务及利用事务DML

    一:默认情况下,MySQL采用autocommit模式运行.这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中.默认级别为不可重复读. 二:会造成隐式提交的语句以下语 ...

随机推荐

  1. 商品类目和商品大广告的Redis缓存

    (dubbo)主要的实现类: 商品类目的Redis缓存 com.bjsxt.ego.portal.service.impl.PortalItemCatServiceImpl package com.b ...

  2. python3如何随机生成大数据存储到指定excel文档里

    本次主要采用的是python3的第三方库xlwt,来创建一个excel文件.具体步骤如下: 1.确认存储位置,文件命名跟随时间格式 2.封装写入格式 3.实现随机数列生成 4.定位行和列把随机数写入 ...

  3. HDU 全国多校第四场 题解

    题解 A AND Minimum Spanning Tree 参考代码: #include<bits/stdc++.h> #define maxl 200010 using namespa ...

  4. 深入学习 OLED Adafruit_SSD1306库(8266+arduino)

    QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷 单片机菜鸟博哥CSDN 1.前言 SSD1306屏幕驱动库,最出名应该就是u8g2,读者可以参考 玩转u ...

  5. 【大厂】389- 解密国内BAT等大厂前端技术体系-阿里篇(长文建议收藏)

    进入2019年,大前端技术生态似乎进入到了一个相对稳定的环境,React在2013年发布至今已经6年时间了,Vue 1.0在2015年发布,至今也有4年时间了. 整个业界在前端框架不断迭代中,也寻找到 ...

  6. iOS 类别 类扩展 简要说明

  7. Django大纲

    Django框架 ........ 2.聚合查询 分组 F与Q查询 字段 及其 参数 | 数据库的三大范式 3.orm查询优化 MTV与MVC模型 choice参数 ajax serializers ...

  8. 使用 Vue + axios 时,返回状态200,返回值被浏览器拦截

    目录 一.前言 二.解决方案 1. 在全局定义 2. 单独定义 一.前言 在使用 Vue + TypeScript + axios 时,后端已经配置了Cors的前提下,但是在请求接口的时候,返回状态为 ...

  9. ajax数据交互

    目录 一.ORM查询优化 1-1. only与defer 1-2. select_related与prefatch_related 二.MTV与MVC模型 三.choices参数 四.AJAX 4-1 ...

  10. eclipse 导入别人拷贝过来的工作空间项目

    切换自己的工作空间 File --> Import --> Existing Project into Workspace --> 选择项目根目录 --> 确定 如果你的ecl ...