SQL - 对行进行分类

时间:2013-10-08 16:53:47

标签: sql sql-server sql-server-2008-r2

以下是我正在使用的结果集。我想要的是一个额外的列,它将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

1 个答案:

答案 0 :(得分: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方法 - 例如this answer中的方法,它是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