GROUP BY TOP N应用场景

因为工作原因,前段时间遇到这样的问题游戏角色合服,但是每个区服下同一个账号只能保留3个角色,那么问题来了,挖掘机技术那家强?

可能有的同学还是没明白这是怎样的应用场景,举个例子:


上面数据场景从,现在要求单科前两名同学的成绩。

现在怎么来解决这样的问题?

通过分析可知,我们现在是要在每一科两面找到前2位成绩排名的信息。

很遗憾的告诉大家,其实Oracle和MSSQL都是有自带函数rownumber() over(partition by col1 order by col2)

   row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序);

   rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内);

   dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。相比之下row_number是没有重复值的.

MySQL好像还没这样的函数,Over函数都没,如果你愿意的话可以写了一个Over函数,但是这里就不讨论了,我只说一个能直接查询的语句。

SELECT * FROM (    select *,@num := if(@group = `course`, @num + 1, 1) as row_number,@group := course as sub_group
    from Points order by course,point desc)    as x
WHERE x.row_number<=2;

SQL中有几点要给大家说明一下@num相当于我们自己给的一个排序码,然后这个排序码是根据sub_group来分隔的,也就是说一个group里面都有一个唯一不重复的排序码,有了这个排序码过后我们最后在这个大的结果集里面就可以用这个排序码作为前几名同学的筛选条件出最后的数据了。

注意一点,这里在每个分组里面的我的排序码是全自增的,没有实现前面rank()和dense_rank()这样的功能。


既然都说了MSSQL有这样的函数总要拉出来溜溜啥。

SELECT [name],[course],[point]
FROM
(SELECT [name],[course],[point],
ROW_NUMBER() OVER ( PARTITION BY [course] ORDER BY [point] DESC ) AS RowNumber
FROM [dbo].[Points]) AS X
WHERE X.RowNumber<=2

这个主题就讨论到此,有交流或者有更好实现方法的同学一定@我额。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值