SQL分组取前N条记录
SQL分组取前N条记录
实际业务中有这样这样一个需求,,有6种不同的测试项目,每个项目对应很多小游戏(改善方案),客户要求测试完成后,每周进行小游戏的循环推送,每种项目每次推送5个小游戏。
假如A项目对应的小游戏有8个,,那么第一周则推送第1-5个,第二周则推送6、7、8、1、2,以此方式进行循环。
单个项目还好说,但是6种项目怎么搞?!懵逼。。想不出来,,好吧,用存储过程搞定了。但是,在前期摸索的过程中,发现好多猿猿也有类似的需求,,只不过,我的需要循环。那么,,倘若不循环,值进行一次推送呢?6个项目一起,每种项目取前5项?可以学习下~
以网上都能找到的例子来说:[^1]
1 | -- 查询每门课程的前2名成绩 |
查看表中所有数据:
1 | select * from StudentGrade ORDER BY subid asc,grade desc |
两种解决方案:
1 | -- 第一种 |
对于第一种方案我是这么理解的,,因为b.subId=a.subId
,a、b两表相连,以subId进行区分,类似分组。以科目一为例,,
- 若
a.grade=73
,则b表中的科目一中>73
分的共有3项,而条件要求count(1)<2
,这样显然是不符合要求的,所以科目一的73分不行; - 同理92分。
- 若
a.grade=93
,count(1)=1 < 2
,符合要求~ - 若
a.grade=97
,count(1)=0 < 2
,符合要求~
完美~
本来也是有点想不明白的,但是看到下面这句,,诶,有点意思,,噢~了然!
每取每一条记录,判断同一个班级,大于当前成绩的同学是不是小于2个人[^2]
对于第二种方案,,有一种奇技淫巧,就是把a、b两表的数据都查询出来
1 | SELECT |
如此看来,清楚明了,,因为a.subid=b.subid and a.grade<b.grade
,所以第2行a表的93分和b表的97分相连了,又因为count(b.stuid)<2
,所以只取了a表每个科目的前2项。若我们只取a表的数据,后3列消失,,完美~
这个,,就这样吧,剩下的就是实操了,还是自己亲身command+R
运行一下,体会更深~