目前8.0及以上版本是支持row_number( ) over( )的,至于5.X,可以通过变量的方式实现。
简单测试如下:求每个人创建角色,按创建时间倒序排列
select create_person,
if(@create_person = a.create_person, @curRank := @curRank + 1, @curRank := 1) AS row_cnt,
@create_person := a.create_person,
create_time
from (select distinct create_person, create_time
from sys_role
where create_person in ('甲','乙')
order by create_person, create_time desc) a,
(select @create_person := null, @curRank := 0) temp;
具体细节可参考:Mysql5.X实现row_number( ) over( )分组排序
取主体每天的次序
select ent_code,
@curRank := if(@ent_code = ent_code and date(@call_time) = date(call_time), @curRank + 1, 1) AS call_rank,
@ent_code := ent_code AS ent_code_var,
@call_time := call_time AS call_time_var,
call_time,
status,
date(call_time) AS call_date,
now() as create_time
from (select ent_code, call_time, status
from abr_call_task
where date(call_time) = date(curdate())
order by ent_code, date(call_time), call_time) a,
(select @curRank := 0, @ent_code := '', @call_time := '1970-01-01') AS init_vars;
这段SQL代码是用来查询一个名为abr_call_task
的表中的数据,并按照一定的规则为每条记录计算一个排名(call_rank
)。这个排名是基于ent_code
(实体代码)和call_time
(呼叫时间)两个字段的组合,针对每天的记录分别计算。以下是代码的逐行解释:
-
查询开始:从
abr_call_task
表中选择ent_code
(实体代码)、call_time
(呼叫时间)和status
(状态)三列。 -
子查询限制:在子查询中,通过
WHERE date(call_time) = date(curdate())
限制只选取今天的记录,即call_time
的日期等于当前日期的记录。 -
排序:子查询的结果按
ent_code
升序排序,对于每个ent_code
内部再按call_time
升序排序。这样可以确保同一实体同一天内的记录顺序正确。 -
变量初始化:外面的查询引入了一个自定义变量初始化部分,声明了三个变量:
@curRank := 0
初始化排名计数器。@ent_code := ''
初始化实体代码变量,初始为空字符串。@call_time := '0000-00-00'
初始化一个基准时间变量,设置为无效日期,以确保首次比较时能正确进入ELSE
分支。最好改为1970-01-01
-
排名计算:使用
@curRank
变量动态计算每条记录的排名。计算规则基于以下条件:- 如果当前记录的
ent_code
与前一条记录相同,且今天的日期与前一条记录的日期相同,则排名加1(表示是同一个实体在同一天的下一次呼叫)。 - 否则,排名重置为1(表示是新的实体或新的日期的第一次呼叫)。
- 如果当前记录的
-
变量赋值:同时,每次循环都会更新
@ent_code
和@call_time
变量的值,为下一次循环的比较做准备。 -
输出列:最终查询输出包括:
ent_code
:实体代码。call_rank
:根据上述规则计算的排名。ent_code_var
和call_time_var
:这两个额外的列实际上是对计算过程中用到的变量的输出,一般情况下可能不是必须的,除非有特殊用途。call_time
:呼叫时间。status
:状态。call_date
:呼叫时间的日期部分。create_time
:当前查询执行的时间。
整体而言,这段代码旨在为今天每个实体的呼叫记录生成一个基于呼叫时间的连续排名,适用于需要对每日呼叫活动进行排序和计数的场景。
取主体近七天数据的次序:
select ent_code,
if(@ent_code = a.ent_code, @curRank := @curRank + 1, @curRank := 1) AS call_rank,
@ent_code := a.ent_code,
call_time,
status,
now() as create_time
from (select ent_code, call_time, status
from abr_call_task
where call_time >= curdate() - interval 6 day
order by ent_code, call_time) a,
(select @ent_code := null, @curRank := 0) temp