The difference between RANK() and DENSE_RANK() is that RANK() leaves gaps in the ranking sequence when there are ties. Let us see this function through an example.

SELECT Empno, Ename, Job, Mgr, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Rank,
DENSE_RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Drank
FROM Emp ORDER BY SAL Desc NULLS LAST;

Compare the difference in the last columns of this output.

sql_tutorial_rank_1

Note: To see rows having not null data, we can use the available oracle clause – NULLS FIRST and NULLS LAST which determines the position of rows with NULL values in the ordered query.

If the sequence is in descending order, then NULLS LAST implies that NULL values are smaller than non-NULL ones and rows with NULLs will appear at the bottom of the list. If the NULLS FIRST | NULLS LAST clause is omitted, then NULL values are considered larger than any other values and their ordering position depends on the ASC | DESC arguments.

Using RANK() to Obtain a Top-N Query

Again we are taking the same table example

SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM (SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank < 6;

To obtain a top-N query, use RANK() in a subquery and then apply a filter condition outside the subquery. The output is shown below:

sql_tutorial_rank_2

Using the same query with a little modification, you can retrieve the bottom-five employees by salary:

SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM (SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER (ORDER BY SAL ASC NULLS FIRST) AS Emp_Rank
FROM Emp ORDER BY SAL ASC NULLS FIRST)
WHERE Emp_Rank < 6;

The output now will be:

sql_tutorial_rank_3

Also, to get better result, here is more help: Ranking functions can be used to operate within groups, too—that is, the rank value gets reset whenever the group changes. This is achieved with a PARTION BY subclause. Here is the syntax to retrieve the top employee by salary per manager group:

SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM (SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER (PARTITION BY MGR ORDER BY MGR, SAL DESC NULLS LAST)
AS Emp_Rank
FROM Emp ORDER BY MGR, SAL DESC NULLS LAST)
WHERE Emp_Rank = 1;

The output is:

sql_tutorial_rank_4

Related Posts

  1. SQL TIPS : Writing Multiple Column Subqueries
  2. SQL Tutorial : Converting Rows to Columns
  3. Introduction to JOINS in SQL Server
  4. Encryption and Decryption in SQL Server 2005
  5. UNIX Command “find” – Tutorial

Tags: , , , , ,

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>