mysql实现ORACLE 中ROWNUM函数
2016-12-09 10:05
134 查看
前端时间由于工作需要,要实现这样的一个功能:给的原始数据为多个大类,每个大类下面有很多小类,指标为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;
原始数据模型为+---------+---------------+-----------------+-----------------+-----------------------+---------------+
| 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;
相关文章推荐
- 用链表实现的MYSQL、MSSQL和oracle密码暴破C程序
- 与Oracle有所不同,ibatis中实现获取mysql自增序列值
- Oracle,SQl,MySql实现分页查询
- mysql中实现类似oracle中的nextval函数
- MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能优化
- 选择一定的日期oracle与mysql的实现
- Mysql实现oracle decode()函数
- MySQL实现Oracle的rownum伪列
- sqlserver ,mysql,oracle 语句实现分页
- 用Mysql怎样实现Oracle中的SYS_CONNECT_BY_PATH函数和START WITH ...CONNECT BY PRIOR方法
- 在ORACLE、MSSQL、MYSQL中树结构表递归查询的实现方法
- [ORACLE]ORACLE 实现mysql中的limit 功能
- 3大数据库(Sql-Server,MySql和Oracle)的分页SQL语句实现
- Oracle中的ROWNUM rowid 以及MySQL中实现rownum功能类似的语句
- MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能
- mysql类似oracle的row_number实现
- ORACLE与MYSQL的双数据库系统实现应用程序兼容
- MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能.
- ORACLE的几个函数在MYSQL里面的简单实现
- 说一下mysql,oracle等常见数据库的分页实现方案?