Difference between Rank and Dense Rank in SQL
By Sriram
Updated on Jul 07, 2026 | 5 min read | 3.51K+ views
Share:
All courses
Certifications
More
By Sriram
Updated on Jul 07, 2026 | 5 min read | 3.51K+ views
Share:
RANK() and DENSE_RANK() are SQL window functions used to assign rankings based on the values in a result set. Both assign the same rank to rows with identical values, but they differ in how they handle the next rank. RANK() skips rank numbers after a tie, while DENSE_RANK() continues with the next consecutive rank without leaving gaps.
In this blog, we’ll demystify the differences between RANK and DENSE RANK using real-world examples, practical SQL syntax, performance tips, and use cases to help you decide which one to use and when.
Overcome the challenges of NoSQL with a strong foundation in data science and machine learning. Explore our Data Science and Machine Learning Courses to master database management and advanced data techniques today!
Popular upGrad Programs
Parameter |
RANK() |
DENSE_RANK() |
| Ranking Logic | Assigns the same rank to ties, then skips the next rank(s) | Assigns the same rank to ties, no ranks are skipped |
| Gaps in Ranking | Yes – introduces gaps after duplicates | No – ranks remain consecutive even with ties |
| Use Case | Best for ranking where position matters (e.g., leaderboard) | Best for reports with strict rank order continuity |
| Output Behavior (with Ties) | Ties get same rank, next rank jumps ahead | Ties get same rank, next rank is just one higher |
| Syntax | RANK() OVER (PARTITION BY ... ORDER BY ...) | DENSE_RANK() OVER (PARTITION BY ... ORDER BY ...) |
| Performance | Nearly identical performance | Nearly identical performance |
| First Rank Assigned | Always starts from 1 | Always starts from 1 |
| Result Consistency | Varies when there are ties | More consistent in sequential ranking |
| Gap Sensitivity | Sensitive to duplicates – causes rank jumps | Ignores gaps caused by duplicates |
| Sorting Requirement | Requires ORDER BY in OVER() clause | Requires ORDER BY in OVER() clause |
| Standard Compliance | Part of SQL:2003 standard | Part of SQL:2003 standard |
| Ideal For | Competitive rankings, top-N with tie handling | Business reports, non-skip rank listings, product/category sorting |
Also Read:
Let’s take a simple dataset called sales_data:
Employee_ID |
Employee_Name |
Revenue |
| 101 | Alice | 1000 |
| 102 | Bob | 900 |
| 103 | Charlie | 900 |
| 104 | David | 800 |
| 105 | Eva | 700 |
SELECT Employee_Name, Revenue,
RANK() OVER (ORDER BY Revenue DESC) AS rank_position
FROM sales_data;
Output:
Employee_Name |
Revenue |
rank_position |
| Alice | 1000 | 1 |
| Bob | 900 | 2 |
| Charlie | 900 | 2 |
| David | 800 | 4 |
| Eva | 700 | 5 |
Note: Rank 3 is skipped due to the tie between Bob and Charlie.
SELECT Employee_Name, Revenue,
DENSE_RANK() OVER (ORDER BY Revenue DESC) AS dense_rank_position
FROM sales_data;
Output:
Employee_Name |
Revenue |
dense_rank_position |
| Alice | 1000 | 1 |
| Bob | 900 | 2 |
| Charlie | 900 | 2 |
| David | 800 | 3 |
| Eva | 700 | 4 |
Note: No ranks are skipped—ranking remains dense.
Must Read:
RANK() is a window function in SQL used to assign a unique rank to rows within a result set based on the specified order of values. It is typically used with the OVER() clause and ORDER BY to generate rankings within partitions.
However, if two or more rows have the same value, RANK() assigns them the same rank—but skips the next rank(s), creating gaps.
Take your data science skills to the next level with these top courses:
SELECT column1, column2,
RANK() OVER (PARTITION BY columnX ORDER BY columnY DESC) AS rank
FROM your_table;
Example:
Consider a sales table:
Employee |
Revenue |
| Alice | 1000 |
| Bob | 900 |
| Charlie | 900 |
| Dave | 800 |
Using RANK() on Revenue:
Employee |
Revenue |
Rank |
| Alice | 1000 | 1 |
| Bob | 900 | 2 |
| Charlie | 900 | 2 |
| Dave | 800 | 4 |
Note: Rank 3 is skipped due to tie.
Use Cases:
Also Read:
Recommended Courses to upskill
Explore Our Popular Courses for Career Progression
DENSE_RANK() is a window function in SQL that assigns ranks to rows based on a specified order—but unlike RANK(), it does not skip ranks when duplicate values occur. This ensures consecutive ranking even when there are ties.
It’s especially useful when you want no gaps in the ranked output.
SELECT column1, column2,
DENSE_RANK() OVER (PARTITION BY columnX ORDER BY columnY DESC) AS dense_rank
FROM your_table;
Example:
Using the same sales table:
Employee |
Revenue |
| Alice | 1000 |
| Bob | 900 |
| Charlie | 900 |
| Dave | 800 |
With DENSE_RANK() on Revenue:
Employee |
Revenue |
Dense_Rank |
| Alice | 1000 | 1 |
| Bob | 900 | 2 |
| Charlie | 900 | 2 |
| Dave | 800 | 3 |
Note: No skipped ranks—ranks are dense and consecutive.
Must Read:
Key Difference from RANK():
While both functions assign the same rank to tied values, DENSE_RANK() does not leave gaps in the sequence—unlike RANK().
Choosing between RANK() and DENSE_RANK() depends on how you want to handle ties in your result set and the business context of your report.
In short, choose RANK() for accuracy with position gaps, and DENSE_RANK() for sequential clarity without gaps.
Must Check:
Even experienced developers can trip up when working with RANK() and DENSE_RANK(). Here are some frequent errors:
Mistake |
Why It Happens |
How to Fix It |
| Missing ORDER BY in OVER() clause | Without ORDER BY, ranking logic is undefined | Always specify ORDER BY inside the OVER() clause |
| Assuming ranks are unique | Ties result in duplicate ranks | Use ROW_NUMBER() if you need unique values |
| Not using PARTITION BY when needed | Ranks calculated over full dataset instead of group | Add PARTITION BY to segment results (e.g., by department) |
| Expecting continuous ranking from RANK() | RANK() introduces gaps | Use DENSE_RANK() for continuous ranking |
| Wrong column in ORDER BY | Leads to incorrect rank calculations | Double-check sorting logic based on requirement |
| Using RANK in WHERE clause directly | Window functions can't be used in WHERE | Use subqueries or CTEs to filter on ranks |
Subscribe to upGrad's Newsletter
Join thousands of learners who receive useful tips
While RANK() and DENSE_RANK() are powerful, their performance can degrade with large datasets if not optimized properly.
Aspect |
Insight |
Optimization Tip |
| Execution Time | Both functions use sorting; expensive on large datasets | Create indexes on columns used in ORDER BY |
| Memory Usage | Sorting over wide partitions consumes memory | Minimize partition size when possible |
| Parallelism | Modern SQL engines parallelize window functions | Use efficient query plans and review EXPLAIN plans |
| Indexing | No direct index usage for window functions | But indexes on ORDER BY columns can improve sort performance |
| CTE/Subquery Overuse | Over-nesting leads to redundant computation | Materialize intermediate results or use temp tables for reuse |
| Filtering Ranked Rows | Filtering ranks requires another layer (CTE or subquery) | Use WITH clause and filter in outer query for clarity and speed |
Both RANK() and DENSE_RANK() are powerful tools for ranking data, but the choice depends on the context of your analysis.
Similar Read: Check our Top Differences Between Blogs
The difference between RANK and DENSE_RANK in SQL is how they handle duplicate values. Both assign the same rank to tied rows, but RANK() skips the next rank after a tie, while DENSE_RANK() continues with the next consecutive rank without leaving gaps.
DENSE_RANK() is a SQL window function that assigns rankings based on the specified sorting order. Rows with identical values receive the same rank, and the next unique value gets the immediately following rank. This makes it ideal for reports where continuous ranking is required.
Use ROW_NUMBER() when every row needs a unique sequence number. Choose RANK() when tied values should create gaps in rankings, such as sports leaderboards. Select DENSE_RANK() when rankings should remain consecutive, making it suitable for reports, dashboards, and category-based analysis.
Yes. These functions are commonly used in advanced SQL for customer segmentation, sales reports, product rankings, financial analytics, employee performance tracking, and business intelligence dashboards. They simplify analytical queries while producing meaningful rankings across grouped or ordered datasets.
The difference between RANK and DENSE_RANK in SQL determines how tied values appear in reports. Competitive applications usually prefer RANK() because it preserves ranking positions, while business reports and dashboards often use DENSE_RANK() to display consecutive rankings without skipped numbers.
In most SQL databases, ROW_NUMBER() and RANK() have very similar performance because both are window functions. Query speed depends more on indexing, sorting, partitions, and dataset size than on the ranking function itself. Proper query optimization has a much greater impact.
Yes. Both functions work with the PARTITION BY clause to calculate rankings separately within each group. This approach is widely used for department-wise employee rankings, region-wise sales reports, category-based product analysis, and other grouped business scenarios.
Understanding the difference between RANK and DENSE_RANK in SQL demonstrates your knowledge of window functions and analytical queries. Interviewers often ask candidates to explain tie handling, compare ranking functions, and write SQL queries for practical business reporting scenarios.
Yes. Both functions can appear in the same query to compare different ranking approaches. This is useful for analytical reports where you want to display rankings with gaps alongside continuous rankings and evaluate which output better matches business requirements.
ROW_NUMBER() and DISTINCT serve different purposes. DISTINCT removes duplicate rows, while ROW_NUMBER() assigns sequential numbers to records. When you need to identify or remove specific duplicates while keeping selected rows, ROW_NUMBER() offers much greater flexibility.
Beginners should first understand ROW_NUMBER() because it introduces window functions in a simple way. After that, learning RANK() and DENSE_RANK() becomes easier, helping you solve SQL interview questions, reporting tasks, and real-world data analysis problems more effectively.
681 articles published
Sriram K is a Senior SEO Executive with a B.Tech in Information Technology from Dr. M.G.R. Educational and Research Institute, Chennai. With over a decade of experience in digital marketing, he specia...
Get Free Consultation
By submitting, I accept the T&C and
Privacy Policy
Top Resources