mysql实现rownum()over_mysql--实现oracle的row_number() over功能

有时候我们想要得到每个分组的前几条记录,这个时候oracle中row_number函数使用非常方便,但可惜mysql没有。网上搜了些实现方法。

表flow_task有phaseno(序列号),objectno(编号)等几个字段,我们想实现根据编号字段分组,然后组内根据序列号排序功能

select @rownum:=@rownum+1rownum,a.objectno,a.phaseno,if(@objno=a.OBJECTNO or (@objno is null and a.objectno is null),@rank:=@rank+1,@rank:=1) asrow_number,@objno:=a.OBJECTNOfrom(SELECT * from flow_task order by OBJECTNO,phaseno asc)a,

(select @rownum :=0,@objno:=null,@rank:=0)b

注意:order by OBJECTNO,phaseno asc 分组字段在前,排序字段在后

运行结果:

25d539617b712988ac9b08dd8e8ebe7f.png

原理是,先 order by OBJECTNO,phaseno asc,这样后相同编号的记录会在一块儿,并且已经是phaseno有序asc的

select的字段一个一个的看:

@rownum:=@rownum+1,每一行在上行@rownum变量值的基础上+1

if(@objno=a.OBJECTNO or (@objno is null and a.objectno is null),@rank:=@rank+1,@rank:=1),每一行判断,当前行的objectno(编号)是否等于上一个@objno变量值,如果是在上一个@rank变量值基础上+1,否则@rank赋值1

@objno:=a.OBJECTNO,当前行objectno赋值给变量@objno

ps:如果想要分组后某个字段的几个值,也可以使用group_concat函数

select a.objectno,group_concat(ifnull(a.phaseno,'')) phasenofrom(SELECT * from flow_task order by OBJECTNO,phaseno asc)aGROUP BY a.objectno

运行结果:

41c910d8dafe86338b7a0f7d0251f6ad.png

可以看到,group_concat函数把分组后某个字段的值用,拼接起来

要获取前3个值,使用substring_index函数

select a.objectno,group_concat(ifnull(a.phaseno,'')) phaseno,substring_index(group_concat(ifnull(a.phaseno,'')),',',3) sub_phasenofrom(SELECT * from flow_task order by OBJECTNO,phaseno asc)aGROUP BY a.objectno

c95a4448e86bc0ce2367a8b5dfd01252.png

扩展下:怎样实现oracle中的rank() 和dense_rank()呢?我们知道rank()排序类似:1 2 2 4...,dense_rank()排序类似:1 2 2 3...

rank()实现:

select @rownum:=@rownum+1rownum,a.objectno,a.phaseno,if(@objno=a.OBJECTNO or (@objno is null and a.objectno is null),if(@phaseno=a.phaseno or (@phaseno is null and a.phaseno is null),@rank,if(@sk=0,@rank:=@rank+2,@rank:=@rank+1)),@rank:=1)asrow_number,if(@objno=a.OBJECTNO or (@objno is null and a.objectno is null),if(@phaseno=a.phaseno or (@phaseno is null and a.phaseno is null),@sk:=0,if(@sk=0,@sk:=2,@sk:=1)),@sk:=1)asskip,@objno:=a.OBJECTNO,@phaseno:=a.phasenofrom(SELECT * from flow_task order by OBJECTNO,phaseno asc)a,

(select @rownum :=0,@objno:=null,@phaseno:=null,@rank:=1,@sk:=1)b

468d76f1784839ae8fdc8a61989f5e07.png

dense_rank()实现:

select @rownum:=@rownum+1rownum,a.objectno,a.phaseno,if(@objno=a.OBJECTNO or (@objno is null and a.objectno is null),if(@phaseno=a.phaseno or (@phaseno is null and a.phaseno is null),@rank,@rank:=@rank+1),@rank:=1)asrow_number,@objno:=a.OBJECTNO,@phaseno:=a.phasenofrom(SELECT * from flow_task order by OBJECTNO,phaseno asc)a,

(select @rownum :=0,@objno:=null,@phaseno:=null,@rank:=1)b

3aa804a5024d3782ec23654e6c6558e6.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值