问题描述
我正在使用如下所示的 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
编辑
澄清问题后,需要不同的解决方案,这使用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