如何 row_number() mysql 中的排名数据集

How to row_number() a ranked dataset in mysql

a   b       c   D
X   201801  1   1
X   201802  0   1
X   201803  0   2
X   201804  1   1
X   201805  0   1
Y   201801  1   1
Y   201802  0   1
Y   201803  0   2
Y   201804  1   1
Y   201805  0   1

这是我的数据集中的 3 列 (a、b、c)。如何在 MySQL 中添加新的 D 列? D由c排序,如果当前c和前一个c的值相同则加1,否则从1开始。

这是一个 gaps-and-islands 问题,您要在其中构建具有相同值的相邻记录组。

这里,最简单的方法可能是使用行号之间的差异来定义组:

select a, b, c, 
    row_number() over(partition by a, c, rn1 - rn2 order by b) d
from (
    select t.*,
        row_number() over(partition by a order by b) rn1,
        row_number() over(partition by a, c order by b) rn2
    from mytable t
) t

Demo on DB Fiddle:

a  |      b | c  |  d
:- | -----: | :- | -:
X  | 201801 | 1  |  1
X  | 201802 | 0  |  1
X  | 201803 | 0  |  2
X  | 201804 | 1  |  1
X  | 201805 | 0  |  1
Y  | 201801 | 1  |  1
Y  | 201802 | 0  |  1
Y  | 201803 | 0  |  2
Y  | 201804 | 1  |  1
Y  | 201805 | 0  |  1

我会使用 c 的累加和然后使用 row_number():

来定义组
select t.*,
       row_number() over (partition by a, grp, c order by b) as d
from (select t.*,
             sum(c) over (partition by a order by b) as grp
      from t
     ) t;

这似乎是最简单的解决方案。

Here 是一个 db<>fiddle.