Introduction to SQL DENSE_RANK()
DENSE_RANK() was introduced in SQL Server 2005 and it returns a rank that starts at 1 based on the ordering of the row and there is no gap in ranking values. So DENSE_RANK() returns a rank of the specific row which is one plus distinct rank values that have come before the specific row. The DENSE_RANK() is a window function that assign the rank to rows based on the current partition in the result. If the value is same for two rows then they will receive the same rank which is similar to RANK() which means if there are two rows at rank one and there are a total of four such rows then DENSE_RANK() will return 1,1,2,3 whereas RANK() would return 1,1,3,4.
The following shows the common syntax of a DENSE_RANK() in SQL Server:
DENSE_RANK() OVER (
[PARTITION BY partition_expression, ... ]
ORDER BY sort_expression [ASC | DESC], ...
)
The partitioning and order of rows is defined by OVER clause in a window and so they are called window function and following arguments are used in this clause:
- ORDER BY – It defines the logical order of the rows
- PARTITION BY – It divides the result into separate partitions and the window function is applied individually to every partition.
The return type of this function is bigint. DENSE_RANK() function is non-deterministic as opposed to deterministic functions which return the same result at any time. When this function is called it may return a different result at a different time even if the database state remains same.
Examples of SQL DENSE_RANK()
Let us discuss examples of SQL DENSE_RANK().
Example #1
Creating table inserting rows and using DENSE_RANK()
CREATE TABLE dense_rank_tutorial(
alphabet VARCHAR(10)
);
INSERT INTO dense_rank_tutorial(alphabet) VALUES('A'),('B'),('B'),('C'),('C'),('D'),('E');
SELECT alphabet,
DENSE_RANK() OVER (ORDER BY alphabet) my_dense_rank
FROM dense_rank_tutorial;
The result set is as follows:
We have created a table and inserted values then used the DENSE_RANK() to get the rank of the alphabets. We have ordered the ranking by alphabet. Since B and C are repeated, they have same rank, and since we are using dense rank functions so the ranks are not skipped and we use the distinct rank value that have came before B or C and then added 1 to get the ranks.
Example #2
Simple example with DENSE_RANK()
SELECT emp_name,emp_gender,emp_salary,
DENSE_RANK() OVER (ORDER BY emp_salary desc) AS DenseRank
FROM Employee;
The result set is as follows:
This is the basic example in which we select name, gender, and salary from Employee table and used DENSE_RANKfunction to get the rank of salary of each employee. As you can see average of Tom and Ron each has 9500so the rank is 1. Subsequently the ranksare calculated for the rest of the entries. Notice that Jodi has rank of 2 and not 3 since we have used dense rank. If we have used normal rank function then it would have skipped rank 2 and given rank 3 for Jodi.
Example #3
Using DENSE_RANK() to find Nth highest salary
SELECT * FROM Employee ORDER BY emp_salary DESC
The result set is as follows:
This gives the salary of all employees in descending order
WITH SalaryResult AS
(
SELECT emp_gender,emp_salary,emp_name,
DENSE_RANK() OVER (ORDER BY emp_salary desc) AS SalaryDenseRank
FROM Employee
)
SELECT TOP 1 emp_salary,emp_name FROM SalaryResult WHERE SalaryDenseRank = 1
The result set is as follows:
Here we have used DENSE_RANK() to calculate the rank of salary of each employee. But we have wrapped it in a CTE(Common Table Expression) SalaryResult so we can use it in the next query.
The following shows the common syntax of a CTE in SQL Server if you are not familiar with it:
WITH expression_name[(column_name [,...])]
AS
(CTE_definition)
SQL_statement;
So, in the subsequent query we have used SalaryResult CTE and returned the employee salary and name of the person whose dense rank is 1.
WITH SalaryResult AS
(
SELECT emp_gender,emp_salary,emp_name,
DENSE_RANK() OVER (ORDER BY emp_salary desc) AS SalaryDenseRank
FROM Employee
)
SELECT TOP 1 emp_salary,emp_name FROM SalaryResult WHERE SalaryDenseRank = 2
The result set is as follows:
In this example we have written a similar query but in this case we have used second rank and we got the result using DENSE_RANK(). Instead if we have used RANK() then the result set will be empty as there is no second rank as we can see in full result set TOM and RON shares same salary.
Example #4
Using DENSE_RANK() with PARTITION BY clause
SELECT emp_gender,emp_salary,emp_name,
DENSE_RANK() OVER (PARTITION BY emp_gender ORDER BY emp_salary desc) AS SalaryDenseRank
FROM Employee;
The result set is as follows:
In this, we have used DENSE_RANK() and partitioned the data using gender so now this function work within the window of the partition. Now we can use this to our advantage in the next query
WITH SalaryResult AS
(
SELECT emp_gender,emp_salary,emp_name,
DENSE_RANK() OVER (PARTITION BY emp_gender ORDER BY emp_salary desc) AS SalaryDenseRank
FROM Employee
)
SELECT TOP 1 emp_salary,emp_name,emp_gender FROM SalaryResult WHERE SalaryDenseRank= 3 and emp_gender ='Female'
The result set is as follows:
In this query we got the rankings from DENSE_RANK() and using a SQL CTE we get the result of a female employee with dense rank 3 and her name is Sara. This is achieved by partitioning the data according to gender to get the ranking of male and female employee separately.
Conclusion
Hopefully, now you know what DENSE_RANK() is in SQL server and how it is used to get the ranks from the values specified in a given column.
Recommended Articles
We hope that this EDUCBA information on “SQL DENSE_RANK()” was beneficial to you. You can view EDUCBA’s recommended articles for more information.