Comparing SQL Window Functions: ROW_NUMBER vs RANK vs DENSE_RANK Explained

Learn the differences between SQL window functions ROW_NUMBER, RANK, and DENSE_RANK with easy-to-understand examples for beginners.

SQL window functions are powerful tools for performing calculations across a set of table rows related to the current row. Among these, ROW_NUMBER, RANK, and DENSE_RANK are commonly used to assign ranks or numbering within partitions of data. Understanding their differences is important for producing the desired result in your queries.

Let's break down each function with simple explanations and examples to help you decide which one to use.

1. ROW_NUMBER() - This function assigns a unique sequential integer to rows within a partition, starting at 1. Even if there are ties in the ordering column, ROW_NUMBER will give a different number to each row.

sql
SELECT
  EmployeeID,
  Department,
  Salary,
  ROW_NUMBER() OVER (PARTITION BY Department ORDER BY Salary DESC) AS RowNum
FROM Employees;

In this example, ROW_NUMBER numbers employees by salary within each department. Employees with the same salary will have unique row numbers.

2. RANK() - This function assigns a rank to each row within the partition ordered by the specified column. Rows with the same value receive the same rank, but ranks can skip numbers after ties.

sql
SELECT
  EmployeeID,
  Department,
  Salary,
  RANK() OVER (PARTITION BY Department ORDER BY Salary DESC) AS Rank
FROM Employees;

Here, employees with the same salary share the same rank. However, if two employees tie at rank 1, the next rank will be 3, skipping rank 2.

3. DENSE_RANK() - Similar to RANK(), but it does not skip ranks after ties. If two employees share rank 1, the next rank will be 2.

sql
SELECT
  EmployeeID,
  Department,
  Salary,
  DENSE_RANK() OVER (PARTITION BY Department ORDER BY Salary DESC) AS DenseRank
FROM Employees;

This is useful when you want consecutive rankings without gaps, despite ties.

Summary:

- Use ROW_NUMBER() when you need a unique row number per partition. - Use RANK() when you want to give the same rank to ties but keep gaps in ranks. - Use DENSE_RANK() when you want to rank ties equally and keep ranks consecutive without gaps.

These window functions help you rank or number rows based on your query needs. Try experimenting with each on your data to see how their behavior differs!