ROW_NUMBER in MySQL
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
MySQL introduced the ROW_NUMBER() window function in its version 8.0. This function is widely utilized in SQL databases for assigning sequential integers to rows within a result set. It is especially useful for pagination, ranking, and ordering data for analysis purposes.
Overview
ROW_NUMBER() is a window function that assigns a unique sequential integer to rows within a partition of a result set. The syntax for ROW_NUMBER() is straightforward:
Key Components
- OVER(): Required clause that defines the window for the function, including optional partitioning and ordering.
- PARTITION BY 1
<expr>: Optional clause to divide the result set into partitions to which the function is applied. - ORDER BY
<expr>[ASC | DESC]: Required clause to determine the order of rows within each partition.
Use Cases
ROW_NUMBER() is particularly beneficial for tasks such as:
- Pagination: When dealing with large datasets, paginating results for display in smaller chunks can improve performance and user experience.
- Rankings: Assigning ranks to rows based on certain criteria (e.g., sales figures, examination scores).
- Deduplication: Using the
ROW_NUMBER()in conjunction with Common Table Expressions (CTEs) to remove duplicate rows from datasets.
Examples
Example 1: Basic Usage Without Partition
Consider a table employees with columns id, name, and salary:
| id | name | salary |
| 1 | Alice | 70000 |
| 2 | Bob | 80000 |
| 3 | Charlie | 60000 |
| 4 | Dave | 70000 |
Assign a row number to each employee ordered by their salary.
Result:
| id | name | salary | row_num |
| 2 | Bob | 80000 | 1 |
| 1 | Alice | 70000 | 2 |
| 4 | Dave | 70000 | 3 |
| 3 | Charlie | 60000 | 4 |
Example 2: Using Partition By
Given a table sales with columns id, department, and amount:
| id | department | amount |
| 1 | Sales | 5000 |
| 2 | Engineering | 7000 |
| 3 | Sales | 2000 |
| 4 | Engineering | 3000 |
Assign a row number within each department based on the amount.
Result:
| id | department | amount | row_num |
| 3 | Sales | 5000 | 1 |
| 1 | Sales | 2000 | 2 |
| 2 | Engineering | 7000 | 1 |
| 4 | Engineering | 3000 | 2 |
Example 3: Deduplication
To remove duplicates based on a specific column, the ROW_NUMBER() can be combined with a CTE.
Suppose you have employees table that might have duplicate names:
Alternatives and Limitations
Alternatives
While ROW_NUMBER() is powerful, you may sometimes consider using other window functions based on the requirements:
RANK(): Similar toROW_NUMBER(), but assigns the same number to rows with identical values in the ordering column, causing possible gaps in numbering.DENSE_RANK(): Similar toRANK(), but without gaps in numbering for rows with identical values.
Limitations
- Non-deterministic without ORDER BY: The
OVERclause must include anORDER BY, or row numbering is non-deterministic. - Performance: Using window functions on large datasets can be computationally intensive.
Summary Table
| Feature | Description |
| Functionality | Assigns sequential integer to rows in a partition or dataset |
| Required Clauses | OVER(ORDER BY <expr>[, ... ]) |
| Optional Clauses | PARTITION BY <expr>[, ... ] |
| Use Cases | Pagination, ranking, deduplication, etc. |
| Alternatives | RANK(), DENSE_RANK() |
| Limitations | Performance on large datasets, potential for non-determinism |
By leveraging the ROW_NUMBER() function, users can efficiently perform a variety of tasks that require ranking, ordering, or even deduplication of records, enhancing both performance and scalability in data handling.

