[关闭]
@Catyee 2021-08-10T14:21:45.000000Z 字数 1082 阅读 506

mysql group by

mysql


对group by的探究来源于一道面试题:

mysql中group by会进行排序吗?

凭我的想象,group by的作用是分组,然后和聚合函数配合使用,根本不需要排序,确实在sql标准中group by是不需要排序的,这可以在oracle、postgresql数据库上得到验证,因为oracle、postgresql都严格遵守了sql标准。但是mysql还真不一样,mysql在很多地方并没有遵守sql标准,很多标准sql不允许使用的语法在mysql中都可以使用,但是很多时候会违法关系模型的范式要求。不过MySQL从5.7.5版本开始,已经逐渐走向规范化了。
相关讨论可以参考博客:详细分析SQL语句逻辑执行过程和相关语法

那么回到最初的问题中来,mysql中的group by会进行排序吗?
来看mysql 5.7.32中的情况,下图是表中原始数据:
5.7.32表中原始数据.png-19.5kB
id字段有主键索引,version字段没有任何索引。
对version执行group by的结果如下:
5.7.32的group by结果.png-115kB
无论是从执行结果还是从执行计划中都可以看到group by是进行了排序了的。事实上,group by不仅仅可以排序,甚至还可以指定排序的方式:
5.7.32group by指定排序的方式.png-23.4kB

再看看在mysql 8.0.22版本中的表现,下图是原始数据:
8.0.22的原始数据.png-21.1kB
和之前数据一样,表结构也一样,id是主键,version没有任何索引。
对version的group by的结果:
8.0.22的group by结果.png-98.4kB
无论从执行结果还是执行计划中看到group by都没有进行排序了。事实上mysql是从8.0版本开始group by才不再排序了,之前的版本都会排序。

结论:
mysql在8.0版本之前group by都会默认排序,事实上是先分组再排序,而这其实是不符合SQL标准的,mysql的发展过程中也在逐渐靠近标准,到了8.0版本group by已经不再进行排序了。
扩展:sql server的group by也是会进行排序的,所以mysql并不孤单。

distinct子句用于消除select_list列的重复行,这很容易理解。大多数情况下,distinct子句在功能上都可以认为等价于group by子句。有些distinct不适合做的操作,可以在group by中来完成。
那么在mysql中distinct会排序吗?
distinct结果.png-173.4kB
可以看到无论是5.7还是8.0版本的mysql,distinct都没有进行排序。但是sql server的distinct也会进行排序。

扩展阅读:
http://www.blogdaren.com/post-2269.html
https://zhuanlan.zhihu.com/p/101571164

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注