mysql数据库实现oracle的row_number() over功能

首先申明下,这篇文章并不是严格意思上的原创,是昨天项目上有一个这样的需求,要用到row_number() over()的功能。我也是借鉴了别人的博文的https://www.cnblogs.com/yhzh/p/6222580.html

以下是我写的sql

SELECT
a.ui_class_id as classId,
if(@type=a.ui_class_id OR (@type is null AND a.ui_class_id is null),@num:[email protected]+1,@num:=1) as row_number,
@type:=a.ui_class_id
FROM
(SELECT ui_class_id
FROM db_teaching_pad_result.tb_course_index_anlz
  WHERE DATE_FORMAT(dt_event_time, "%Y-%m-%d") BETWEEN '2017-08-02'AND '2018-08-02'
group  by ui_class_id,date(dt_event_time)  ORDER BYui_class_id, dt_event_time DESC
) a,
(SELECT @num := 0, @type := null) b

对应查询的结果集

mysql数据库实现oracle的row_number() over功能

下来我来解释下思路,思路很简单,如上面的sql,分为表a和表b,表a是我们需要返回的数据集,先将其分组和排序,得到最终结果的前半部分,接着和表b拼接起来。if(@type=a.ui_class_id OR (@type is null AND a.ui_class_id is null),@num:[email protected]+1,@num:=1) as row_number,每行判断当前行的id是否和前一行@type变量的值相等,如果相等,@num:[email protected]+1,否则@num:=1。这里有个地方要注意的是每一行都需要执行重新赋值@type:=a.ui_class_id,这个赋值必须要在判断之后,否则会一直递增。原因我猜测在sql中也是按顺序执行的,先执行的判断,执行判断时@type还没有更新,取的是上一次的值。