根据每行的顺序添加行号

Adding a row number respecting the order of each row

我有一个table这样的

id, period, tag
1     1      A
1     2      A
1     3      B
1     4      A
1     5      A
1     6      A
2     1      A
2     2      B
2     3      B
2     4      B
2     5      B
2     6      A

我想添加一个带有排名的新列,尊重给定我的列 'period' 的行的顺序以获得类似这样的内容

id, period, tag  rank
1     1      A     1
1     2      A     1
1     3      B     2
1     4      A     3
1     5      A     3
1     6      A     3
2     1      A     1
2     2      B     2
2     3      B     2
2     4      B     2
2     5      B     2
2     6      A     3

我能做什么?

我尝试了 rank 和 dense_rank 功能,但没有成功

一种方法是基于 lag():

的累加和
select t.*,
       sum(case when prev_tag = tag then 0 else 1 end) over (partition by id order by period) as rank
from (select t.*, lag(tag) over (partition by id order by period) as prev_tag
      from t
     ) t;

还有 CONDITIONAL_CHANGE_EVENT() 的另一个候选人 代码更少,也非常有效......!

WITH
input(id,period,tag) AS (
          SELECT 1,1,'A'
UNION ALL SELECT 1,2,'A'
UNION ALL SELECT 1,3,'B'
UNION ALL SELECT 1,4,'A'
UNION ALL SELECT 1,5,'A'
UNION ALL SELECT 1,6,'A'
UNION ALL SELECT 2,1,'A'
UNION ALL SELECT 2,2,'B'
UNION ALL SELECT 2,3,'B'
UNION ALL SELECT 2,4,'B'
UNION ALL SELECT 2,5,'B'
UNION ALL SELECT 2,6,'A'
)
SELECT
  *
, CONDITIONAL_CHANGE_EVENT(tag) OVER(PARTITION BY id ORDER BY period) + 1 AS rank
FROM input;
-- out  id | period | tag | rank 
-- out ----+--------+-----+------
-- out   1 |      1 | A   |    1
-- out   1 |      2 | A   |    1
-- out   1 |      3 | B   |    2
-- out   1 |      4 | A   |    3
-- out   1 |      5 | A   |    3
-- out   1 |      6 | A   |    3
-- out   2 |      1 | A   |    1
-- out   2 |      2 | B   |    2
-- out   2 |      3 | B   |    2
-- out   2 |      4 | B   |    2
-- out   2 |      5 | B   |    2
-- out   2 |      6 | A   |    3
-- out (12 rows)
-- out 
-- out Time: First fetch (12 rows): 14.823 ms. All rows formatted: 14.874 ms