为相同的序列元素分配多个连续的重复
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
编辑
问题弄清楚后,需要一个不同的解决方案,这里使用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
我正在使用 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
编辑
问题弄清楚后,需要一个不同的解决方案,这里使用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