mysql分组查询并排序_mysql特殊查询----分组后排序

使用的示例表

学生表----student

表结构

4038269761fc5ca4caf18fb1c36b0494.png

数据

36c6c304b2d17aefaf843c798ca75a1d.png

查询方法

一、第一种方法

我认为这是比较传统,比较容易理解的一种方式,使用自连接,并在连接条件中作比较,之后再对查询条件分组统计,排序。

selecta.id,a.class,a.sourcefrom student a left join student b on a.class=b.class and a.source<=b.sourcegroup bya.class,a.sourceorder by a.class,a.source

结果:

f009eafccad8d4c2cf111688c3381a4d.png

分析一下查询过程:

1、自连接并使用比较条件

selecta.id,a.class,a.source asource,b.source bsourcefrom student a left join student b on a.class=b.class and a.source<=b.sourceorder by a.class,a.source

查询结果:

5a6dc5c560d1b4bab98918e4406e9623.png

334acc55c4ca5fd61b0056d8a777fbb8.png

以上查询数据可以看出,每个班等于或比每一个asource分数多bsource有几条数据,最终,最小的asource会有一个班级人数的数据条数,最大的asource只会有一条数据。这就是排序的依据。

之后,对数据分组。

2、对数据进行分组

select a.id,a.class,a.source asource,count(a.source)from student a left join student b on a.class=b.class and a.source<=b.sourcegroup bya.class,a.sourceorder by a.class,a.source

查询结果:

6004852fb7bfe51ad624e663fe272681.png

以上数据已经可以直观的看出数据被排序后的结果。

3、对分组后的数据截取前N条或后N条

a、首先是保留前N条数据,使用having。

select a.id,a.class,a.source asource,count(a.source)from student a left join student b on a.class=b.class and a.source<=b.sourcegroup bya.class,a.sourcehaving count(a.source)<=3

order by a.class,a.source

查询结果:

cbc7f67ef825086db858b68d4d04b5e1.png

这样截取到的每个班最高的三个分数,因为比较条件是:a.source<=b.source,导致asource最大的分数只有一条,最小的有最多的条数,所以在使用having获得统计数最少的三条数据时,会得到三个最高分。

如果要得到最低的三个分数的数据,就要保证最小的分数有最少的数据(不一定是一条,当有两个最高分)。因为a.source<=b.source比较条件是相互的,所以只需要将asource参与的查询换成bsource,就可以实现获得最少分数的需求。

b、获得后N条数据

select a.id,a.class,b.source bsource,count(b.source)from student a left join student b on a.class=b.class and a.source<=b.sourcegroup bya.class,b.sourcehaving count(b.source)<=3

order by a.class,b.source

查询结果:

35a4fbf8691daed93e35f608051a6b2b.png

二、第二种方法-----只用于分组排序后取前N条数据

1、分组后取前N或后N条,关键在于比较,通过where俩控制查询条数

最大的前3条数据

select * from student asawhere 3>(select count(*) from student where class=a.class and source>a.source)ORDER BY class ,source desc

查询结果:

0c4f039b0388ef09053f22273c7f832d.png

最小的前3条数据

select * from student asawhere 3>(select count(*) from student where class=a.class and source

查询结果:

06b3856a41ca5000d06ea94fdc1b6005.png

这种查询方式,某些逻辑无法理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值