Rank function in MySQL
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
RANK() in MySQL is a window function that assigns an ordered position to each row within a result set or partition. It is especially useful for leaderboards, top-per-group reports, and any query where ties should share the same position instead of receiving arbitrary row numbers.
Basic RANK() Syntax
RANK() is available in MySQL 8.0 and later as part of the window function feature set. The basic shape is:
PARTITION BY is optional. It splits the result into separate groups before ranking. ORDER BY is what defines the ranking itself.
Example: Ranking Employees by Salary
Suppose you have an employees table:
If two employees in the same department have the same salary, they receive the same rank. The next rank then skips ahead.
For example, if salaries rank as 100, 90, 90, 80, the ranks will be 1, 2, 2, 4.
That gap is the defining behavior of RANK().
RANK() vs DENSE_RANK() vs ROW_NUMBER()
These three functions are often confused:
- '
RANK()gives ties the same rank and leaves gaps afterward' - '
DENSE_RANK()gives ties the same rank but does not leave gaps' - '
ROW_NUMBER()gives every row a unique sequence number'
A comparison query makes the difference obvious:
Choose RANK() when ties should visibly affect later positions. Choose DENSE_RANK() when you want tied rows grouped together but still want consecutive numbering.
Ranking Without Partitions
If you omit PARTITION BY, MySQL ranks across the entire result set:
This is useful for a global leaderboard or any whole-table ordering problem.
Filtering Ranked Results
A common pattern is to rank in a subquery or common table expression and then filter the ranked rows:
That returns the top three salary ranks per department, including ties when they fall within the requested rank range.
This pattern is often easier to maintain than trying to simulate ranking with self-joins or user-defined variables, especially now that window functions are built into modern MySQL.
Common Pitfalls
The biggest mistake is expecting RANK() to produce consecutive numbers after ties. That is what DENSE_RANK() does, not RANK().
Another common issue is forgetting that window functions require a meaningful ORDER BY. If the ordering column is ambiguous or not aligned with the business rule, the assigned rank will not match the intended definition.
It is also easy to forget the MySQL version requirement. RANK() depends on window function support, so it is not available in older MySQL versions that predate 8.0.
Summary
- '
RANK()assigns positions within an ordered result set or partition.' - In MySQL, it is used with
OVER (...)and requires anORDER BYinside the window definition. - Tied rows receive the same rank, and later ranks skip numbers.
- Use
DENSE_RANK()if you want ties without gaps. - '
PARTITION BYlets you rank independently inside groups such as departments or categories.'
Related reading
- RDS endpoint name format
- Read-your-own-writes consistency in Cassandra
- Read data from KSQL tables
- Readiness Probe for Redis with large dataset
- Reading data from _transaction_state topic in Kafka 0.11.0.1
- Reading into SQL Server from Kafka feed
- Real-time application newbie - Node.JS + Redis or RabbitMQ -> client/server how?
- Real Time Monitoring Architecture for distributed Database

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.