mysql group by 插件_MySQL之GROUP BY

本文详细介绍了MySQL中的GROUP BY语句,用于根据指定字段对数据进行分组。通过实例展示了如何创建虚拟表并执行其他条件,以及WHERE和HAVING子句的区别。还探讨了ORDER BY用于排序分组结果,以及聚合函数如COUNT(), AVG(), MIN(), MAX()的使用。同时,提到了在特定场景下如何利用子查询和联合查询实现更复杂的分组需求。
摘要由CSDN通过智能技术生成

group by

当前mysql版本8.0.15

1.创建分组

group by根据分组字段将结果集进行分组,可以理解为以分组字段查询出相关结果集,并创建虚拟表,从虚拟表中执行其他条件并返回数据

举例说明:

4483fd536878eab1bf2a8657399c86f5.png

这是原始表

执行sql: select * from users group by name;

创建的虚拟表

id name status

1 123 1

2 (同上) 3

3 before 1

4 (同上) 2

etc.

由于没有其他条件,但是group by 输出结果是对分组字段与对应结果集为一对一的关系,根据默认顺序,对虚拟表进行合并,

id为1,2的结果合并为1条,根据默认规则,取第一条;id为3,4的同理

输出结果:

4db1eb44111b87f7c6a51ea6558564b2.png

对多个字段分组,即对虚拟表取多个分组字段与结果集的一对多关系;

6d12ea129ac7d252729745baada2f3e9.png

注意id为1的记录和id为5的记录,name和status字段一致

执行 select * from users group by name, status;

输出结果:

411ad82df2e43a2960faa945d2a93819.png

没有id为5的记录,因为该记录在虚拟表中和id为1的记录在同一组,只输出了一条,即id为1的记录

2.过滤分组

当我们需要对取得虚拟表的数据的过程中进行过滤时,可以使用where

select * from users where name='123' or name='before' group by name;

18248772a5a7f8046e5adaec40f19390.png

当我们需要对取得虚拟表的数据后的分组过程中进行过滤时,可以使用having

select * from users group by status having count(*) > 2;

11422fbccbe48cffac86d510616bdf75.png

两者的区别:

作用过程,上文所叔;

作用对象,根据上文补充,where作用的是表的行,having作用的是分组;

子句不同,where由于不存在任何结果集,不能使用聚合函数;而having作用于分组结果,通常使用聚合函数做更进一步的分组;

两者可以联合使用,如select * from users where name='123' or name='before' group by name having count(*)>1;

3.排序

对虚拟表的分组结果进行排序,在group by 的最后添加 order by子句;

但是目前我没有找到对虚拟表得到数据前对每一组进行排序的简单方法;这个的实现方式在下文,利用子查询或联合查询实现;

不过如果对虚拟表得到数据前的所有组做统一排序,和对虚拟表的分组结果进行排序是一样的

select * from users where name='123' or name='before' group by name order by id desc;

4.聚合函数

聚合是对结果集的作用,因此where语句不可以使用聚合函数,而having、select后,由于得到了结果集,因此可以使用聚合函数

常用的聚合函数:COUNT(), AVG(),MIN(),MAX()

select id, name, status from users where name='123' or name='before' group by name having max(status);

e21bec16486768dd9a130b566563303e.png

这句的having其实是失效的,因为having后一定是过滤条件

select id, name, status from users where name='123' or name='before' group by name having max(status) > 1;

59948e71ffe78859d35ce8417192fb05.png

5.转化为子查询、联合查询

以上使用方式还存在很多不足,比如

不能在得到虚拟表后、分组时,根据虚拟表中具体数据进行分组;比如取每个结果集中最大的status以及所对应的记录输出

需要利用子查询、联合查询实现

场景一:取每个name组中,最大的staus的所对应的记录

10b1a743074735e33b121102a183606b.png

子查询:select * from (select * from users group by name, status order by status desc) u group by name;

61c96dcfc703696f89c5a674806dddcf.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值