Here are simple definitions, purposes, example queries, and a simulation using MS SQL for ROW_NUMBER(), RANK(), and DENSE_RANK():
1. ROW_NUMBER()
Definition:
The ROW_NUMBER() function assigns a unique sequential integer to rows within a result set, starting from 1 for the first row. It doesn’t leave gaps even if there are duplicate values.
Purpose:
Used when you need to assign a unique identifier to each row, for example, when paging or generating an ordered list of records.
Query Example:
SELECT
ROW_NUMBER() OVER (ORDER BY Salary DESC) AS RowNum,
EmployeeID,
FirstName,
LastName,
Salary
FROM Employees;Simulation:
Assume we have the following Employees table:
| EmployeeID | FirstName | LastName | Salary |
|---|---|---|---|
| 1 | John | Doe | 5000 |
| 2 | Jane | Smith | 6000 |
| 3 | Bob | Johnson | 6000 |
| 4 | Alice | Brown | 4500 |
The query will return:
| RowNum | EmployeeID | FirstName | LastName | Salary |
|---|---|---|---|---|
| 1 | 2 | Jane | Smith | 6000 |
| 2 | 3 | Bob | Johnson | 6000 |
| 3 | 1 | John | Doe | 5000 |
| 4 | 4 | Alice | Brown | 4500 |
2. RANK()
Definition:
The RANK() function assigns a rank to each row in the result set based on a specified order. If two rows have the same value (tie), they will receive the same rank, but the next rank will skip one.
Purpose:
Used to assign ranks, where ties in values result in gaps in the rank sequence.
Query Example:
SELECT
RANK() OVER (ORDER BY Salary DESC) AS Rank,
EmployeeID,
FirstName,
LastName,
Salary
FROM Employees;Simulation:
Using the same Employees table:
| EmployeeID | FirstName | LastName | Salary |
|---|---|---|---|
| 1 | John | Doe | 5000 |
| 2 | Jane | Smith | 6000 |
| 3 | Bob | Johnson | 6000 |
| 4 | Alice | Brown | 4500 |
The result of the RANK() query:
| Rank | EmployeeID | FirstName | LastName | Salary |
|---|---|---|---|---|
| 1 | 2 | Jane | Smith | 6000 |
| 1 | 3 | Bob | Johnson | 6000 |
| 3 | 1 | John | Doe | 5000 |
| 4 | 4 | Alice | Brown | 4500 |
Notice the gap between rank 1 and rank 3 due to the tie between Jane and Bob.
3. DENSE_RANK()
Definition:
The DENSE_RANK() function also assigns a rank to each row, but unlike RANK(), it does not leave gaps when there are ties. If two rows are tied for rank 1, the next rank will be 2.
Purpose:
Used when you want to rank rows without leaving any gaps in the ranking sequence, even if there are ties.
Query Example:
SELECT
DENSE_RANK() OVER (ORDER BY Salary DESC) AS DenseRank,
EmployeeID,
FirstName,
LastName,
Salary
FROM Employees;Simulation:
Again, using the same Employees table:
| EmployeeID | FirstName | LastName | Salary |
|---|---|---|---|
| 1 | John | Doe | 5000 |
| 2 | Jane | Smith | 6000 |
| 3 | Bob | Johnson | 6000 |
| 4 | Alice | Brown | 4500 |
The result of the DENSE_RANK() query:
| DenseRank | EmployeeID | FirstName | LastName | Salary |
|---|---|---|---|---|
| 1 | 2 | Jane | Smith | 6000 |
| 1 | 3 | Bob | Johnson | 6000 |
| 2 | 1 | John | Doe | 5000 |
| 3 | 4 | Alice | Brown | 4500 |
In this case, no rank is skipped, even with the tie between Jane and Bob, so they both have rank 1, and the next rank is 2 (for John), then 3 (for Alice).
Summary of Differences:
| Function | Handling of Ties | Gap in Ranking | Example Ranks |
|---|---|---|---|
| ROW_NUMBER() | No ties (unique number for each row) | No gap | 1, 2, 3, 4 |
| RANK() | Tied rows get the same rank | Yes (skips next rank after ties) | 1, 1, 3, 4 |
| DENSE_RANK() | Tied rows get the same rank | No gap | 1, 1, 2, 3 |
These functions are useful for creating ranked data and managing how to handle ties in SQL queries.