SQL 服务器中的组排名
Ranking by Groups in SQL SERVER
我需要按 'String' 和 'Is_sep' 对以下组进行排名,并按 'Id' 保持顺序:
(SQL 服务器)
ID | String | Is_Sep | Rank | Rank_DESC
1 | XX | 0 | 1 | 3
2 | XX | 0 | 2 | 2
3 | XX | 1 | 3 | 1
4 | XX | 0 | 1 | 3
5 | XX | 0 | 2 | 2
6 | XX | 1 | 3 | 1
7 | YY | 0 | 1 | 4
8 | YY | 0 | 2 | 3
9 | YY | 0 | 3 | 2
10 | YY | 1 | 4 | 1
11 | ZZ | 0 | 1 | 2
12 | ZZ | 1 | 2 | 1
13 | ZZ | 0 | 1 | 3
14 | ZZ | 0 | 2 | 2
15 | ZZ | 1 | 3 | 1
知道怎么做吗?
谢谢!
这是一种间隙和孤岛问题,其中 is_sep
标记每个孤岛的终点。
我会使用 window 总和来定义组,然后 row_number()
:
select
id,
string,
sep,
row_number() over(partition by string, grp order by id) rn,
row_number() over(partition by string, grp order by id desc) rn_desc
from (
select
t.*,
sum(is_sep) over(partition by string order by id desc) grp
from mytable t
) t
order by id
请注意,对于此示例数据,分区中实际上不需要 string
,因为 is_sep
还表示 string
值之间的转换。所以这同样有效:
select
id,
string,
is_sep,
row_number() over(partition by grp order by id) rn,
row_number() over(partition by grp order by id desc) rn_desc
from (
select
t.*,
sum(is_sep) over(order by id desc) grp
from mytable t
) t
order by id
id | string | is_sep | rn | rn_desc
-: | :----- | -----: | -: | ------:
1 | XX | 0 | 1 | 3
2 | XX | 0 | 2 | 2
3 | XX | 1 | 3 | 1
4 | XX | 0 | 1 | 3
5 | XX | 0 | 2 | 2
6 | XX | 1 | 3 | 1
7 | YY | 0 | 1 | 4
8 | YY | 0 | 2 | 3
9 | YY | 0 | 3 | 2
10 | YY | 1 | 4 | 1
11 | ZZ | 0 | 1 | 2
12 | ZZ | 1 | 2 | 1
13 | ZZ | 0 | 1 | 3
14 | ZZ | 0 | 2 | 2
15 | ZZ | 1 | 3 | 1
我需要按 'String' 和 'Is_sep' 对以下组进行排名,并按 'Id' 保持顺序: (SQL 服务器)
ID | String | Is_Sep | Rank | Rank_DESC
1 | XX | 0 | 1 | 3
2 | XX | 0 | 2 | 2
3 | XX | 1 | 3 | 1
4 | XX | 0 | 1 | 3
5 | XX | 0 | 2 | 2
6 | XX | 1 | 3 | 1
7 | YY | 0 | 1 | 4
8 | YY | 0 | 2 | 3
9 | YY | 0 | 3 | 2
10 | YY | 1 | 4 | 1
11 | ZZ | 0 | 1 | 2
12 | ZZ | 1 | 2 | 1
13 | ZZ | 0 | 1 | 3
14 | ZZ | 0 | 2 | 2
15 | ZZ | 1 | 3 | 1
知道怎么做吗?
谢谢!
这是一种间隙和孤岛问题,其中 is_sep
标记每个孤岛的终点。
我会使用 window 总和来定义组,然后 row_number()
:
select
id,
string,
sep,
row_number() over(partition by string, grp order by id) rn,
row_number() over(partition by string, grp order by id desc) rn_desc
from (
select
t.*,
sum(is_sep) over(partition by string order by id desc) grp
from mytable t
) t
order by id
请注意,对于此示例数据,分区中实际上不需要 string
,因为 is_sep
还表示 string
值之间的转换。所以这同样有效:
select
id,
string,
is_sep,
row_number() over(partition by grp order by id) rn,
row_number() over(partition by grp order by id desc) rn_desc
from (
select
t.*,
sum(is_sep) over(order by id desc) grp
from mytable t
) t
order by id
id | string | is_sep | rn | rn_desc -: | :----- | -----: | -: | ------: 1 | XX | 0 | 1 | 3 2 | XX | 0 | 2 | 2 3 | XX | 1 | 3 | 1 4 | XX | 0 | 1 | 3 5 | XX | 0 | 2 | 2 6 | XX | 1 | 3 | 1 7 | YY | 0 | 1 | 4 8 | YY | 0 | 2 | 3 9 | YY | 0 | 3 | 2 10 | YY | 1 | 4 | 1 11 | ZZ | 0 | 1 | 2 12 | ZZ | 1 | 2 | 1 13 | ZZ | 0 | 1 | 3 14 | ZZ | 0 | 2 | 2 15 | ZZ | 1 | 3 | 1