为相同的序列元素分配多个连续的重复

Assign the same sequence elements a number of consecutive repetitions

我正在使用 SQL 服务器 table,它看起来像这样:

diff nom rec_num
-7 abc 9
-6 abc 9
-5 abc 7
-4 abc 6
-3 abc 6
-2 abc 6
-1 abc 13
-7 fav 7
-6 fav 9
-5 fav 9
-4 fav 13
-3 fav 7
-2 fav 7
-1 fav 7

真实的table要大很多,这是样本。

我需要为 table 中的每个 rec_num 指定它们连续重复的次数。比如有一个序列5 5 4 4 4 3 5 5 5 5 1,那么工作的结果应该是2 2 3 3 3 1 4 4 4 4 1。我需要的是连续 的重复次数 ,而不是重复的总次数。

使用ROW_NUMBER的组合:

with cte as (
  select diff, nom, rec_num,
  row_number() over (partition by nom order by nom, diff desc) rn1,
  row_number() over (partition by nom, rec_num order by nom, diff desc) rn2
  from t)
  
 select diff, nom, rec_num,
   row_number() over (partition by nom, rn1 - rn2 order by nom, diff desc) as con_repeats
from cte

我得到了以下 table

diff nom rec_num con_repeats
-1 abc 13 1
-2 abc 6 1
-3 abc 6 2
-4 abc 6 3
-5 abc 7 1
-6 abc 9 1
-7 abc 9 2
-1 fav 7 1
-2 fav 7 2
-3 fav 7 3
-4 fav 13 1
-5 fav 9 1
-6 fav 9 2
-7 fav 7 1

但我需要 table 看起来像这样:

diff nom rec_num con_repeats
-1 abc 13 1
-2 abc 6 3
-3 abc 6 3
-4 abc 6 3
-5 abc 7 1
-6 abc 9 2
-7 abc 9 2
-1 fav 7 3
-2 fav 7 3
-3 fav 7 3
-4 fav 13 1
-5 fav 9 2
-6 fav 9 2
-7 fav 7 1

我该怎么做?

您只需使用 group by

即可完成此操作
with x as (
    select nom, rec_num, Count(*) n
    from t
    group by nom,rec_num
)
update t set t.con_repeats=x.n
from x
join t on t.nom=x.nom and t.rec_num=x.rec_num

Fiddle

编辑

问题弄清楚后,需要一个不同的解决方案,这里使用window functions来识别重复值的孤岛,updatable CTE将每个孤岛组的max count应用到来源 table:

with groups as (
    select t.*,
        Dense_Rank() over (partition by nom order by (rn - rn2), rec_num) as grp,
        Row_Number() over (partition by nom, (rn - rn2), rec_num order by diff) as c
    from(
        select t.*, row_number() over (partition by nom order by diff) as rn, Row_Number() over (partition by nom, rec_num order by diff) as rn2
        from t
    )t
),
cnt as (
    select *, Max(c) over (partition by nom,grp) maxc
    from groups
)
update cnt set con_repeats=maxc;

select * from t;

看到这个New fiddle

-- Please see if this helps.

SELECT t1.*, repeats FROM tbl t1
INNER JOIN 
    (SELECT repeats, nom, rec_num FROM (
        (SELECT COUNT(*) repeats, nom, rec_num FROM tbl GROUP BY nom, rec_num))t
     ) t2
ON t2.nom = t1.nom and t2.rec_num = t1.rec_num
ORDER BY nom, diff DESC