mysql实现ORACLE 中ROWNUM函数

前端时间由于工作需要,要实现这样的一个功能:给的原始数据为多个大类,每个大类下面有很多小类,指标为DFlow,现在需要根据DFlow由大到小选出每个大类中小类的top3。但是刚开始却始终出现一个问题,就是第一次选出的数据都是全部,在执行第二次往后就正常了,后来研究了一下,终于找到这个的所在,现在拿出来和大家做一下分享。

原始数据模型为+---------+---------------+-----------------+-----------------+-----------------------+---------------+
| id      | bigprotocolId | smallprotocolId | bigprotocolName | smallprotocolName     | DFlow         |
+---------+---------------+-----------------+-----------------+-----------------------+---------------+
| 2358622 |             4 |            1032 | Web??           | ??                    |   51239912.00 |
| 2358623 |             1 |              10 | P2P????         | ??????                |     535515.00 |
| 2358624 |             4 |            1037 | Web??           | ???                   |       2738.00 |
| 2358625 |             6 |            1044 | HTTP????        | ????                  |     257973.00 |
| 2358626 |             9 |             788 | ????            | HotSpot               |       3039.00 |
| 2358627 |             2 |            2580 | ????            | Wephone?VoIP??        |        527.00 |
| 2358628 |            11 |             277 | ????            | ??163??               |     591286.00 |
| 2358629 |             3 |            2581 | ????            | Badoo                 |        360.00 |
| 2358630 |             3 |            1055 | ????            | ??                    |          1.00 |
| 2358631 |             5 |            2593 | ??????          | 360???????????        |     347534.00 |
| 2358632 |             2 |            1315 | ????            | eSpace_VoIP           |         95.00 |


第一次执行sql为 select t.bigprotocolId,t.smallprotocolId,t.bigprotocolName,t.smallprotocolName,t.DFlow from (select *, @rank:=if(@bigprotocolName = b.bigprotocolName, @rank + 1, 1) as rank,(@bigprotocolName:=b.bigprotocolName) as Name from (select * from FlowHuaweiDPITotalTestSql order by bigprotocolId,DFlow desc) as b) as t where t.rank<=3 ;发现没有实现功能,在执行一次就成功了,这是为什么呢?后来拆分这个语句终于找到原因了。


第一次执行select *, @rank:=if(@bigprotocolName = b.bigprotocolName, @rank + 1, 1) as rank,(@bigprotocolName:=b.bigprotocolName) as bigprotocolName from (select * from FlowHuaweiDPITotalTestSql order by bigprotocolId,DFlow desc) as b;的时候,结果是给每行添加的rank编号都是1,所以最后在选择小于3的时候就选了全部的数据。当在第二次执行这个sql的时候发现rank的编号就正常了,依次是每个大类下小类的编号,这个时候就会想到应该是初始化的问题,没有对bigprotocolName,rank的值进行初始化,导致了在第一次执行的时候失败。于是对sql进行了修改如下:


新的sql为 select *, @rank:=if(@bigprotocolName = b.bigprotocolName, @rank + 1, 1) as rank,(@bigprotocolName:=b.bigprotocolName) as bigprotocolName from (select * from FlowHuaweiDPITotalTestSql order by bigprotocolId,DFlow desc) as b,(select @bigprotocolName := null, @rank := 0) as a \G;   相比于上面的sql他添加了(select @bigprotocolName := null, @rank := 0) as a,对这两个值进行了初始化,于是第一次执行的时候也就成功实现了需求。最后完整的sql为


select t.bigprotocolId,t.smallprotocolId,t.bigprotocolName,t.smallprotocolName,t.DFlow from (select *, @rank:=if(@bigprotocolName = b.bigprotocolName, @rank + 1, 1) as rank,(@bigprotocolName:=b.bigprotocolName) as Name from (select * from FlowHuaweiDPITotalTestSql order by bigprotocolId,DFlow desc) as b,(select @bigprotocolName := null, @rank := 0) as a) as t where t.rank<=3 \G;


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值