mysql实现ORACLE 中ROWNUM函数

来源:互联网 发布:java中重载的意义 编辑:程序博客网 时间:2024/06/06 07:18

前端时间由于工作需要,要实现这样的一个功能:给的原始数据为多个大类,每个大类下面有很多小类,指标为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
原创粉丝点击