mysql 5.7 中 rank 函数的替代方案,用于通过 cr-id 查找最新记录组

Alternative of rank function in mysql 5.7 to find out latest rescord grouped by cr-id

我有一个 table 像这样的东西:

cr-id  prod-name  timestamp 

p1     prod-1     2020-10-06 01:00:00.0
p1     prod-2     2020-10-06 02:00:00.0
p1.    prod-1     2020-07-03 08:32:00.0
p2.    prod-2     2020-06-01 07:39:00.0
p2.    prod-1     2020-04-05 03:32:00.0
p3.    prod-2     2020-03-02 02:23:00.0
p3.    prod-2     2020-07-04 02:23:00.0

我想对按 cr-id 分组的最新日期使用新的列排名。所以我的输出结果应该是这样的:

 cr-id  prod-name  timestamp              rank

p1     prod-1     2020-10-06 01:00:00.0    2
p1     prod-2     2020-10-06 02:00:00.0    1
p1.    prod-1     2020-07-03 08:32:00.0    3
p2.    prod-2     2020-06-01 07:39:00.0    1
p2.    prod-1     2020-04-05 03:32:00.0    2
p3.    prod-2     2020-03-02 02:23:00.0    2
p3.    prod-2     2020-07-04 02:23:00.0    1

我使用的是 mysql-5.7,因此 RANK 函数在这里不起作用。你能帮我高效地实现这个目标吗?

一个选项使用相关子查询:

select t.*,
    (
        select 1 + count(*) 
        from mytable t1 
        where t1.cr_id = t.cr_id and t1.timestamp > t.timestamp
    ) rn
from mytable t

另一个选项:

SELECT t1.`cr-id`, t1.`prod-name`, t1.`timestamp`, COUNT(*) `rank`
FROM src_table t1
JOIN src_table t2 ON t1.`cr-id` = t2.`cr-id`
                 AND t1.`timestamp` >= t2.`timestamp`
GROUP BY t1.`cr-id`, t1.`prod-name`, t1.`timestamp`

添加排名列后,执行:

set @last='';
set @rank=NULL;
update yourtable
    set rank=if(
        @last=(@last:=cr_id),
        (@rank:=@rank+1),
        (@rank:=1)
    )
order by cr_id,`timestamp`;