One of the most obvious and useful set of window functions are ranking functions where rows from your result set are ranked according to a certain scheme. There are three ranking functions:

  • RANK()



… assigns unique numbers to each row within the PARTITION given the ORDER BY clause. So you’d get:

Note that some SQL dialects (e.g. SQL Server) require an explicit ORDER BY clause in the OVER() clause:

The above query returns:



… behaves like ROW_NUMBER(), except that “equal” rows are ranked the same. If we substitute RANK() into our previous query:

… then the result we’re getting is this:

As you can see, much like in a sports ranking, we have gaps between the different ranks. We can avoid those gaps by using



Trivially, DENSE_RANK() is a rank with no gaps, i.e. it is “dense”. We can write:

… to obtain


One interesting aspect of DENSE_RANK() is the fact that it “behaves like” ROW_NUMBER() when we add the DISTINCT keyword.

… to obtain


In fact, ROW_NUMBER() prevents you from using DISTINCT, because ROW_NUMBER() generates unique values across the partition before DISTINCT is applied:

DISTINCT has no effect:


Share This Via: