SQL SERVER – Ranking Functions – RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) – Day 12 of 35

In this blog post we will discuss about Ranking Functions like RANK( ), DENSE_RANK( ), and ROW_NUMBER( ).

Ranking Functions (Part 1)

There are four ranking functions in SQL server. Today we will look at RANK( ), DENSE_RANK( ), and ROW_NUMBER( ).These functions all have the same basic behavior. Where they differ is in the handling of tie values. These three functions produce identical results, until a tying value in your data is present.

SQL SERVER - Ranking Functions - RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) - Day 12 of 35 j2p_12_1

Until the tie data is encountered, the results are identical (see Josh and Kevin’s score of 9.6. We will explain more on this later. Let’s look at RANK( ) using a Grant table example sorted by largest to smallest grant amount (descending sort order).

SQL SERVER - Ranking Functions - RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) - Day 12 of 35 j2p_12_2

A smart way to begin your ranking functions is to first write a SELECT statement with an ORDER BY clause. Every ranking function retrieves your sort order from the ORDER BY clause. In this case, the item is grant amount arranged in descending order. Add RANK( ) to the SELECT list. Remember that all ranking functions need an OVER( ) clause. If you then SQL Server reminds you as you can see from the error message below.

SQL SERVER - Ranking Functions - RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) - Day 12 of 35 j2p_12_3

All ranking functions need an OVER( ) clause and SQL Server provides another syntax clue for the ORDER BY clause. Ranking functions need the ORDER BY information to appear as an argument of the OVER( ) clause Move the ORDER BY clause inside the parentheses of OVER( ) clause.

SQL SERVER - Ranking Functions - RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) - Day 12 of 35 j2p_12_4

Now we can look at how RANK() works with ties. The Grant table ranked over the Amount column, showing 2 pairs of tied amounts. There is a 2 way tie for 4th place so both the grants of $21,000 get a rank of 4. After that there is no 5th place grant. There is a 6th place grant so after ties you get a gap to match the numbered order. Observe that no ORDER BY clause follows the FROM clause, since we moved it in into the OVER( ) clause. Examine what the RANK( ) function has done here. We see straightforward rankings of 1, 2, and 3 for the first three unique amount values. Notice the tie for fourth place. Then there’s another tie for the next place, which is ranked as 6. After that we get to 8th place as seen in the figure below.

SQL SERVER - Ranking Functions - RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) - Day 12 of 35 j2p_12_5

How about Dense_Rank? After the 2 way tie for 4th place the next value will get 5th place. There will be no gaps after the tie with the DENSE_RANK(). DENSE_RANK( ) is very useful for finding the five highest distinct amounts, because it finds each amount and has no gap in its numbering sequence.

SQL SERVER - Ranking Functions - RANK( ), DENSE_RANK( ), and ROW_NUMBER( ) - Day 12 of 35 j2p_12_6

Note: If you want to setup the sample JProCo database on your system you can watch this video. For this post you will want to run the SQLQueriesChapter7.0Setup.sql script from Volume 2.

Question 12

The figure below shows the scores of 6 contest winners. Tom is the highest
and Eric made 6th place. There were 6 people but only 5 distinct scores.

5 Highest Scores 5 Highest Distinct Scores

9.9 9.9

9.8 9.8

9.7 9.7

9.6 9.6

9.6 9.2

You are writing a query to list the 5 highest distinct scores. The Ranked field should be called ScoreRating. You have written the following code.

SELECT * FROM
(SELECT  *  More code here.
FROM [Contestants])  AS ContestantFinal
WHERE ScoreRating <= 5

What code will achieve this goal?

  1. SUM(*) OVER(ORDER BY Score DESC) as ScoreRating
  2. RANK( ) OVER(ORDER BY Score DESC) as ScoreRating
  3. COUNT(*) OVER(ORDER BY Score DESC) as ScoreRating
  4. DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

Rules:

Please leave your answer in comment section below with correct option, explanation and your country of resident.
Every day one winner will be announced from United States.
Every day one winner will be announced from India.
A valid answer must contain country of residence of answerer.
Please check my facebook page for winners name and correct answer.
Winner from United States will get Joes 2 Pros Volume 2.
The contest is open till next blog post shows up at which is next day GTM+2.5.

Reference: Pinal Dave (https://blog.sqlauthority.com)

Joes 2 Pros, Ranking Functions, SQL Scripts, SQL Server
Previous Post
SQL SERVER – Tips from the SQL Joes 2 Pros Development Series – Advanced Aggregates with the Over Clause – Day 11 of 35
Next Post
SQL SERVER – Tips from the SQL Joes 2 Pros Development Series – Ranking Functions – Advanced NTILE in Detail – Day 13 of 35

Related Posts

103 Comments. Leave new

  • DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Chetan – USA

    Reply
  • Rene Alberto Castro Velasquez
    August 12, 2011 7:18 am

    Correct answer is No. 4
    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating
    as we want to get the five highest distinct amounts.

    Rene Castro
    El Salvador

    Reply
  • Shatrughna Kumar
    August 12, 2011 7:23 am

    Correct option is 4.
    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    New Delhi

    Reply
  • This time I guess you have a typo. For the five highest distinct scores none of your choices give the answer mostly because of typo in main body of the question. 2) and 4) are syntactically correct

    4) is the one closest to the solution as it presents only the distinct values of scores

    The question should have
    “WHERE ScoreRating <= 5" instead of "WHERE ScoreRating = 5"

    SELECT * FROM
    (SELECT *, DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating
    FROM [Contestants]) AS ContestantFinal
    WHERE ScoreRating <= 5

    Leo Pius
    USA

    Reply
  • The correct option is #4

    DENSE_RANK() OVER (ORDER BY Score DESC) as ScoreRating

    DENSE_RANK provides distinct scores.

    Reply
  • Forgot to add in my prev. reply – I’m from USA

    The correct option is #4

    DENSE_RANK() OVER (ORDER BY Score DESC) as ScoreRating

    DENSE_RANK provides distinct scores.

    Reply
  • Correct answer is option #4

    4.DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    becuase as explained in the article above DENSE_RANK( ) is very useful for finding the five highest distinct amounts, because it finds each amount and has no gap in its numbering sequence.

    Thanks.

    Country – India

    Reply
  • Actually, when I think a bit more, the question asked is quite tricky.

    If we want to list just the five distinct top scores, we can do:

    ;with Scores as (select Score, dense_rank() over (partition by Score DESC) as [ScoreRank] from ContestantFinal)

    select Distinct Score from Scores where ScoreRank <=5

    ———————————————————————-
    With the query #4

    SELECT * FROM
    (SELECT *, DENSE_RANK OVER (ORDER BY Score DESC) as ScoreRating
    FROM [Contestants]) AS ContestantFinal
    WHERE ScoreRating = 5

    we will get all people who were on the 5th place.

    I am from USA

    Reply
  • Aditya Bisoi (@AdityaBisoi07)
    August 12, 2011 8:54 am

    Question 12

    Ans : DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Chennai, INDIA

    Reply
  • Answer : option 4

    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Nikhildas
    Cochin,INDIA

    Reply
  • The correct ans is #4

    Reply
  • Uday Kumar B R
    August 12, 2011 9:58 am

    What code will achieve this goal?
    Main query is itself wrong
    as where condition looking for ScoreRating=5
    This wont give Correct result
    Does not give any distinct values.

    If In where condition ScoreRating<6 then we can use option 4 in sub-query
    Answer is 4
    4. DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating
    Gives but does not give the distinct ratings.

    wrong:
    1. SUM(*) OVER(ORDER BY Score DESC) as ScoreRating
    Because * can not be used in Sum Function
    2. RANK( ) OVER(ORDER BY Score DESC) as ScoreRating
    Because Misses the rank numbers
    3. COUNT(*) OVER(ORDER BY Score DESC) as ScoreRating
    count(*) will count for all rows..this result we are not expecting and

    Reply
  • Option 4 is correct.

    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    As we need to return the scorerating 5, it is only possible if we use DENSE_RANK here.

    INDIA

    Reply
  • correct answer is option 4
    India

    Reply
  • Answer 4:

    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating
    as we want to get the five highest distinct amounts.

    India

    Reply
  • 4th option.

    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Arjun
    India.

    Reply
  • Question 12
    4. DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Reply
  • Krishnakant Joshi
    August 12, 2011 10:23 am

    a query to list the 5 highest distinct scores write the following code.

    SELECT * FROM

    (SELECT * , DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    FROM [Contestants]) AS ContestantFinal

    WHERE ScoreRating <=5

    Ans :DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Krishnakant Joshi
    India

    Reply
  • Varinder Sandhu
    August 12, 2011 10:25 am

    Correct answer is 4 as

    DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating

    Varinder Sandhu (India)

    Reply
  • Rajneesh Verma
    August 12, 2011 10:30 am

    Hi,
    Option 4 is correct Answer:
    “DENSE_RANK( ) OVER(ORDER BY Score DESC) as ScoreRating”

    Thanks…
    Rajneesh Verma
    (INDIA)

    Reply

Leave a Reply