đ DENSE_RANK() is a SQL window function that assigns a rank to each row based on a specified ordering. Rows with the same ordering value receive the same rank, but unlike RANK(), no rank numbers are skipped after tied values.
đ What is DENSE_RANK()?
DENSE_RANK() evaluates rows according to the ORDER BY clause inside the OVER() clause. When two or more rows have the same ordering value, they receive the same rank, and the next distinct value receives the next consecutive rank.
Information
đ¯ Why Use DENSE_RANK()?
DENSE_RANK() is useful when tied values should receive the same ranking while maintaining consecutive rank numbers.
- đ Rank records without gaps.
- đ Handle tied values fairly.
- đ Build consecutive leaderboards.
- đ Compare performance within groups.
- đ Generate analytical reports.
đ Sample Table
| EmployeeID | EmployeeName | Department | Salary |
|---|---|---|---|
| 101 | Alice | Sales | 70000 |
| 102 | Bob | Sales | 65000 |
| 103 | Charlie | IT | 80000 |
| 104 | David | IT | 80000 |
| 105 | Emma | HR | 55000 |
đ Basic Syntax
DENSE_RANK() Syntax
SELECT
column1,
column2,
DENSE_RANK() OVER (
ORDER BY column_name
) AS DenseRank
FROM table_name;The ORDER BY clause determines the ranking order.
đĄ Example: Rank Employees by Salary
Overall Salary Ranking
SELECT
EmployeeName,
Salary,
DENSE_RANK() OVER (
ORDER BY Salary DESC
) AS SalaryRank
FROM Employees;đ Example Output
| EmployeeName | Salary | SalaryRank |
|---|---|---|
| Charlie | 80000 | 1 |
| David | 80000 | 1 |
| Alice | 70000 | 2 |
| Bob | 65000 | 3 |
| Emma | 55000 | 4 |
Remember
đĄ Example: Rank Within Each Department
Department Ranking
SELECT
EmployeeName,
Department,
Salary,
DENSE_RANK() OVER (
PARTITION BY Department
ORDER BY Salary DESC
) AS DepartmentRank
FROM Employees;PARTITION BY restarts the ranking independently for each department.
đ Example Output
| Employee | Department | Salary | DepartmentRank |
|---|---|---|---|
| Alice | Sales | 70000 | 1 |
| Bob | Sales | 65000 | 2 |
| Charlie | IT | 80000 | 1 |
| David | IT | 80000 | 1 |
| Emma | HR | 55000 | 1 |
đĄ Example: Top Two Salary Ranks
Retrieve Top Salary Ranks
SELECT *
FROM (
SELECT
EmployeeName,
Salary,
DENSE_RANK() OVER (
ORDER BY Salary DESC
) AS SalaryRank
FROM Employees
) RankedEmployees
WHERE SalaryRank <= 2;This query returns employees whose salaries fall within the top two distinct salary ranks.
âī¸ DENSE_RANK() vs RANK() vs ROW_NUMBER()
| Function | Ties Share Rank | Gaps After Ties |
|---|---|---|
| ROW_NUMBER() | â No | Not Applicable |
| RANK() | â Yes | â Yes |
| DENSE_RANK() | â Yes | â No |
đŧ Real-World Applications
- đ Competition leaderboards with tied positions.
- đ° Rank employees by salary.
- đ Rank products by sales.
- đ Identify top-performing customers.
- đ Display student rankings with tied scores.
đī¸ Database Compatibility
| Database System | DENSE_RANK() Support |
|---|---|
| MySQL | â Supported in MySQL 8.0 and later. |
| PostgreSQL | â Fully supported. |
| SQL Server | â Fully supported. |
| Oracle | â Fully supported. |
| SQLite | â Supported in SQLite 3.25.0 and later. |
â ī¸ Common Mistakes
- â Confusing DENSE_RANK() with RANK().
- â Omitting the ORDER BY clause inside OVER().
- â Using DENSE_RANK() when every row requires a unique number.
- â Forgetting to use PARTITION BY when rankings should restart for each group.
Warning
â ī¸ Best Practices
Best Practice
đ Key Points to Remember
- đ DENSE_RANK() is a SQL window function.
- đ Equal values receive the same rank.
- đ No gaps appear after tied values.
- đ It requires the OVER() clause.
- đ PARTITION BY restarts rankings within groups.
- đ It is ideal for consecutive rankings and analytical reports.