T-SQL 2005 Enhancements - Ranking - RANK(), DENSE_RANK() and NTILE()

The other day, I introduced the first of the new ranking functions - ROW_NUMBER().  Today I want to touch on the other three of these.

For the code to build the tables we are going to use, get the table create from the first entry in this 2 part series:
http://spaces.msn.com/members/drsql/Blog/cns!1pqLLlQgw9hZKLV1K4eLatKw!241.entry

RANK() give us the position in the set, much like you would expect when you rank sports teams by record.  There may be 10 first place teams, but the 11th team is in 11th place.  Everything works the same as ROWNUMBER, so we won't spend any time discussing how to order these by different values, or how to use PARTITION. 

select value, RANK() over (order by value) as RANK
from  ranking

value      RANK
-----------  --------------------
1           1
1           1
2           3
2           3
3           5
3           5
3           5
3           5
3           5
3           5

With DENSE_RANK, it does not leave gaps, so the 2nd group will be numbered 2, no matter how many values there are in the first group:

select value, DENSE_RANK() over (order by value) as DENSE_RANK
from  ranking

value      DENSE_RANK
-----------  --------------------
1           1
1           1
2           2
2           2
3           3
3           3
3           3
3           3
3           3
3           3

Finally, NTILE() can be used to split the set into equal groups.  For example, if you want to split the data into 2 equal groups, you could do:

select value, NTILE(2) over (order by value) as NTILE
from  ranking

value     NTILE
----------- --------------------
1           1
1           1
2           1
2           1
3           1
3           2
3           2
3           2
3           2
3           2

Or 3:

select value, NTILE(3) over (order by value) as NTILE
from  ranking

value       NTILE
----------- --------------------
1           1
1           1
2           1
2           1
3           2
3           2
3           2
3           3
3           3
3           3

Or 4 (just kidding! Hopefully it is clear by now, or you will probably never get it :))  If you put a value greater than the number of values in the set, you will end up with a slightly weird result:

select value, NTILE(200) over (order by value) as NTILE
from  ranking
value               NTILE
-------------------- --------------------
1                    1
1                    2
2                    3
2                    4
3                    5
3                    6
3                    7
3                    8
3                    9
3                    10

So if had been thinking, hmm, I could calculate percentages of values within the set very easy with this, you sure can, but you would have to have at least 100 rows in the result set.  The maximum value for the parameter of NTILE is the maximum of bigint, though currently in the April CTP, it seems to be just the max of int.  So no more than two billion sets there my friends.

Next time, I think perhaps we will look at INTERSECT and EXCEPT, two really nice little clauses to add to the old tool bag....