当前位置:首页 > 数据库 > SQL使用GROUP BY分组排序问题

SQL使用GROUP BY分组排序问题

2022年11月09日 22:27:41数据库10
当我们想要查询一个单表或者想要JOIN一个表的数据,且需要使用GROUP BY来进行分组时,发现分组之后的顺序又不是我们想要的顺序,怎么办?

例子

测试数据:
SELECT * FROM lesson l ORDER BY l.course_id;

SQL使用GROUP BY分组排序问题 _ JavaClub全栈架构师技术笔记

上面是一个用于测试的数据表,一个course_id对应多个lesson_id,且每个lesson都有自己的start_time。如果我们直接使用GROUP BY把数据根据course_id来进行分组,那么lesson的信息,默认取的是插入时的第一条数据。
直接分组:
SELECT l.course_id,l.start_time FROM lesson l GROUP BY l.course_id;

SQL使用GROUP BY分组排序问题 _ JavaClub全栈架构师技术笔记

这里我们可以结合第一张图来看下,GROUP BY之后,start_time字段的数据就是对应该course_id的第一条数据的时间(逻辑有点绕)。如果我们想要取最早的start_time,我们就要结合ORDER BY,但是MySQL在处理GROUP BY之前,是不会按照我们的ORDER BY先进性排序的。所以,我们看下面这个方法。
使用LIMIT固定数据排序:
SELECT l.course_id,l.start_time FROM (SELECT * FROM lesson l1 ORDER BY l1.start_time ASC LIMIT 10000) l GROUP BY l.course_id;

SQL使用GROUP BY分组排序问题 _ JavaClub全栈架构师技术笔记

注意:这里LIMIT后面的数值要大于表数据总量。
这个语句中我们先根据start_time排序出来一个临时表,且加上LIMIT来固定数据顺序(如果不加LIMIT,GROUP BY依然不会使用我们自定义的排序),之后再分组这个临时表,即可达到我们的目的。
结合图1可以看出,分组之后的start_time已经是对应的course_id的最早那个数据。
使用GROUP_CONCAT来拿到想要的start_time
SELECT l.course_id,MIN(l.start_time) AS start_time FROM lesson l GROUP BY l.course_id;

SQL使用GROUP BY分组排序问题 _ JavaClub全栈架构师技术笔记

这个方法的查询结果和上面是一样的。我们先按照course_id分组,之后用MIN函数取出多个start_time中最小的一个,即可达成展示course_id对应最早start_time的目的。
但这个方法做的是字段聚合,如果我们查询的时候把主键也展示出来,我们就能看出区别了。
方法对比:
SELECT l.lesson_id,l.course_id,l.start_time FROM (SELECT * FROM lesson l1 ORDER BY l1.start_time ASC LIMIT 10000) l GROUP BY l.course_id;
SELECT l.lesson_id,l.course_id,MIN(l.start_time) AS start_time FROM lesson l GROUP BY l.course_id;
result1:

SQL使用GROUP BY分组排序问题 _ JavaClub全栈架构师技术笔记

result2:

SQL使用GROUP BY分组排序问题 _ JavaClub全栈架构师技术笔记

叮!!!在这两个对比中,我们发现start_time所对应的主键,是不一样的,因为下面的这个SQL是在字段上做了聚合处理,实际上start_time对应的真实主键是上面那个SQL执行的结果。如果不考虑这个因素,在数据量较大的情况下,下面的方法要快于上面的方法。
想要深入了解GROUP BY使用时涉及到的排序问题,还需要了解一下MySQL是如何处理GROUP BY的。
这篇博客仅作为笔记,不能够作为很好的指南。深究该问题,请多多查阅MySQL官方文档才是最靠谱的方法。
相关文档连接:MySQL Handling of GROUP BY
最后翻译原文一段话:
Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause.
Result set sorting occurs after values have been chosen, and ORDER BY does not affect which value within each group the server chooses.
Disabling ONLY_FULL_GROUP_BY is useful primarily when you know that, due to some property of the data, all values in each nonaggregated column not named in the GROUP BY are the same for each group.
此外,通过添加ORDER BY子句不能影响从每个组中选择值。
选择值之后,将进行结果集排序,并且ORDER BY不会影响服务器在每个组中选择哪个值。
禁用ONLY_FULL_GROUP_BY非常有用,主要是因为您知道由于数据的某些属性,每个未聚合列中未在GROUP BY中命名的所有值对于每个组都是相同的。
这里提到了ONLY_FULL_GROUP_BY,当我们直接使用GROUP_BY却不在语句中使用聚合函数的话,需要禁用该选项(貌似大部分人都选择禁用了)。

作者:MrXionGe
来源链接:https://blog.csdn.net/qq_31226223/article/details/104519624

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/database/68984.html

标签: group by
分享给朋友:

“SQL使用GROUP BY分组排序问题” 的相关文章

mysql group by 用法解析(详细) + mysql distinct 去重

这篇文章写的很好。 转自:http://blog.tianya.cn/blogger/post_read.asp?BlogID=4221189&PostID=47881614   在使用mysql时,有时需要查询出某个字段不重复的记录,虽然my...

MySQL5.7.5及以上执行group by报错

MySQL5.7.5及以上执行group by报错

MySQL执行报错: [Err] 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'cerebrum_sit.s.id' wh...

SQL: select非group by的字段

使用group by查找或删除重复行,请参考    SQL:查找或删除重复行 在含有Group by子句的查询语句中,对select关键字后的目标列,存在以下规律 使用group by 时,select 涉及的列要么是参...

优化 Group By -- MYSQL一次千万级连表查询优化(转)

优化 Group By -- MYSQL一次千万级连表查询优化(转)

概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上。  这个SQL查询关联两个数据表,一个是攻击IP用户表主要是记录IP的...

Mysql Group by函数用法详解

Mysql Group by函数用法详解

应用场景: 现有表student如下: 需求描述: 需要查询1班的人数: 使用语句: SELECT count(*) from student where class_name ='1班'; 结果显示:...

mysql8.0遇到的一个坑(group by 分组 sql语句的用法)

使用 sql 查询时 mysql 报如下错误, 完整报错如下: ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated col...

mysql rollup语法

MySQL GROUP BY 语句 GROUP BY 语句根据一个或多个列对结果集进行分组。 在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。 GROUP BY 语法 SELECT column_name, functi...

MYSQL数据分组(十三)GROUP BY

MYSQL数据分组(十三)GROUP BY

MySQL GROUP BY子句 GROUP BY子句是 SELECT 语句的可选部分,它将一组行记录按列或表达式的值分组成摘要行记录。GROUP BY子句返回每个分组的一个行记录。换句话说,它减少了在结果集中的行数。 我们经常使用GROUP BY子句在聚合...

【mysql哪些事儿】distinct 和 group by用法总结

【mysql哪些事儿】distinct 和 group by用法总结

   需求是这样的,因为公司现在统计这一块做的不是十分完善,所以每天老板那边会需要根据各种条件的数据统计,因为用户达到了千万级别,所以每次统计查询其消费数据的时候,数据量,都需要手动导出数据来,将这些数据拼接起来,然后做成excel表格的形式,上报给boss。...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。