2

Below is the result set I am working with. What I would like is an additional column that identifies a X number of rows as the same. In my result set, rows 1-4 are the same (would like to mark as 1), rows 5-9 are the same (mark as 2); row 10 (mark as 3)

How is this possible using just SQL? I can't seem to do this using rank or dense_rank functions.

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
Martin Smith
  • 438,706
  • 87
  • 741
  • 845
tad stones
  • 57
  • 6

1 Answers1

5

In general case you can do something like this:

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

In your case you can do it even without 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;

Unfortunately, in SQL Server 2008 you cannot do running total with window function, in SQL Server 2012 it'd be possible to do it with sum([bool]) over(order by ranking).

If you have really big number of rows and your ranking column is unique/primary key, you can use recursive cte approach - like one in this answer, it's fastest one in 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

Community
  • 1
  • 1
Roman Pekar
  • 107,110
  • 28
  • 195
  • 197