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

问题描述

我正在使用如下所示的 sql Server 表:

差异 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

真正的桌子要大得多,这是样本。

我需要为表格的每个 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,rn1 - rn2 order by nom,diff desc) as con_repeats
from cte

我得到了下表

差异 nom rec_num con_repeas
-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

但我需要这样的表格:

差异 nom rec_num con_repeas
-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应用到源表:

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,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,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