【问题标题】:Ranking by Groups in SQL SERVER在 SQL SERVER 中按组排名
【发布时间】:2020-11-21 19:18:51
【问题描述】:

我需要按“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

知道怎么做吗?

谢谢!

【问题讨论】:

  • “排名”是什么意思?你的意思是订购吗?订购后获得行号?或者您的意思是根据某些标准的“相关性”?

标签: sql sql-server sql-order-by window-functions gaps-and-islands


【解决方案1】:

这是一种孤岛问题,is_sep 标志着每个孤岛的尽头。

我会使用窗口总和来定义组,然后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

Demo on DB Fiddlde

编号 |字符串 | 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

【讨论】:

  • sum(is_sep) over (partition by string order by id desc) 真的简单多了。
  • @GordonLinoff:啊,是的,这确实简单多了——不需要coalesce(),也不需要rows between。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 2013-03-08
相关资源
最近更新 更多