2

下面是我正在使用的结果集。我想要的是一个额外的列,它将 X 行标识为相同的。在我的结果集中,第 1-4 行相同(想标记为 1),第 5-9 行相同(标记为 2);第 10 行(标记为 3)

仅使用 SQL 怎么可能?我似乎无法使用 rank 或 dense_rank 函数来做到这一点。

ranking              diff        bool
-------------------- ----------- -----------
1                    0           0
2                    0           0
3                    0           0
4                    0           0
5                    54          1
6                    0           0
7                    0           0
8                    0           0
9                    0           0
10                   62          1
4

1 回答 1

5

在一般情况下,您可以执行以下操作:

select
    t.ranking, t.[diff], t.[bool],
    dense_rank() over(order by c.cnt) as rnk
from Table1 as t
    outer apply (
        select count(*) as cnt
        from Table1 as t2
        where t2.ranking <= t.ranking and t2.[bool] = 1
    ) as c

在您的情况下,即使没有dense_rank()

select
    t.ranking, t.[diff], t.[bool],
    c.cnt + 1 as rnk
from Table1 as t
    outer apply (
        select count(*) as cnt
        from Table1 as t2
        where t2.ranking <= t.ranking and t2.[bool] = 1
    ) as c;

不幸的是,在 SQL Server 2008 中,您不能使用窗口函数进行总计,在 SQL Server 2012 中,可以使用sum([bool]) over(order by ranking).

如果您的行数非常多并且您的ranking列是唯一/主键,则可以使用递归 cte 方法 - 就像这个答案中的一种,它是 SQL Server 2008 R2 中最快的一种:

;with cte as
(
    select t.ranking, t.[diff], t.[bool], t.[bool] as rnk
    from Table1 as t
    where t.ranking = 1
    union all
    select t.ranking, t.[diff], t.[bool], t.[bool] + c.rnk as rnk
    from cte as c
        inner join Table1 as t on t.ranking = c.ranking + 1
)
select t.ranking, t.[diff], t.[bool], 1 + t.rnk
from cte as t
option (maxrecursion 0)

sql fiddle demo

于 2013-10-08T17:07:33.093 回答