mysql oracle over_MySQL实现Oracle中的row_number over函数

update2020.9.11 Oracle的row_number over 该函数不确定在mysql8.0窗口函数是否支持,假如支持就不需要下面这种方式了。

1.首先了解Oracle中的row_number over 函数的作用就是按照某个字段进行分组,分组后再组内按照某个字段排序,且可以打印出一个新的排序的列。

2.MySQL是没有这个函数的,所以我们要想实现,则需要一些特殊方法。

需求如下:

表结构如下

CREATE TABLE `order` (

`XXXX` varchar(10) DEFAULT NULL,

`XXXX` varchar(10) DEFAULT NULL,

`XXXX` varchar(3) DEFAULT NULL,

`XXXX` varchar(100) DEFAULT NULL,

`oprseq` varchar(100) DEFAULT NULL,

`user_number` decimal(22,0) DEFAULT NULL,

`XXXX` varchar(2) DEFAULT NULL,

`order_id` bigint(20) DEFAULT NULL,

`XXXX` date DEFAULT NULL,

`XXXX` date DEFAULT NULL,

`XXXX` tinyint(4) DEFAULT NULL,

KEY `index_i` (`order_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

部分字段进行脱敏,我们关心的字段如下:

oprseq:订单序列号

user_number:用户手机号

order_id:订单号

要求是按照order_id asc limit1000条 其中手机号不能重复,假如有重复的,则取组内order_id最小的那个(asc)

处理sql如下:

select * from (

select @rownum:=@rownum+1 rownum,a.*,

if(@userno=a.user_number or (@userno is null and a.user_number is null),

@rank:=@rank+1,

@rank:=1) as row_number,

@userno:=a.user_number

from(select * from

(select * from order order by order_id asc limit 1000) d

order by user_number, order_id asc

) a,

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

where row_number=1;

sql解释:

1.最内层的一个是按照索引进行一个排序的查询,select * from order order by order_id asc limit 1000,除非数据量非常大,否则这个sql会很快的。

2.(select * from (select * from order order by order_id asc limit 1000) d order by user_number, order_id asc),这个sql是对排序后的1000条数据按照手机号和订单号排序,这样就会把同样手机号的数据放在一起,方便后续对他们进行rank.

3.if(@userno=a.user_number or (@userno is null and a.user_number is null),

@rank:=@rank+1,

@rank:=1) as row_number,

@userno:=a.user_number

这个sql是实现row_number over功能的核心代码,if的作用为:if(condition,a,b),假如条件匹配,则a,否则则b,当然为了处理null的情况,所以又加了一个or 的条件去处理null的情况,上述代码意思是:假如@userno=该行的手机号,则rank+1,否则,rank就会赋值为1,体现到需求上,就是假如手机号有重复的,那么就会对重复的手机号进行累加,否则就对于每个不重复的手机号 rank赋值1 ,@userno本质上是查找这一行数据和上一行数据是否一致,因为在这个sql的后面会对@userno进行赋值,@userno:=a.user_number

4.(select @rownum :=0,@userno:=null,@rank:=0)b) 初始化sql,初始化几个变量的值

5.where row_number=1; 把组内得分第一的取出,其他的抛弃。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值