softwaretips4u Tips that Transform
← Back to Homepage ← Back to Articles

SQL Ranking Functions – RANK(), DENSE_RANK(), ROW_NUMBER()

🔹 Why Ranking Functions?

Ranking window functions assign ordered numbers to rows based on a specified sort expression. They are essential for leaderboards, pagination, top-N analysis, and identifying duplicates.

⚙️ Basic Pattern

SELECT
  column_list,
  RANK() OVER (
    PARTITION BY partition_column
    ORDER BY sort_column DESC
  ) AS rank_value
FROM table_name;

🧠 ROW_NUMBER()

SELECT
  employee_name,
  department,
  salary,
  ROW_NUMBER() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS row_num
FROM employees;
📘 Always produces unique numbers—even when salaries tie.

🧠 RANK()

SELECT
  employee_name,
  department,
  salary,
  RANK() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS rank_pos
FROM employees;
📘 Tied rows share the same rank, and the next rank is skipped (1, 1, 3).

🧠 DENSE_RANK()

SELECT
  employee_name,
  department,
  salary,
  DENSE_RANK() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS dense_rank
FROM employees;
📘 Tied rows share the same rank, but no gaps exist (1, 1, 2).

🧩 Top 3 Salaries per Department

WITH RankedSalaries AS (
  SELECT
    department_id,
    employee_name,
    salary,
    DENSE_RANK() OVER (
      PARTITION BY department_id
      ORDER BY salary DESC
    ) AS rank_in_dept
  FROM employees
)
SELECT *
FROM RankedSalaries
WHERE rank_in_dept <= 3;
📘 Quickly filters each department down to its top earners.

🧠 Pagination with ROW_NUMBER

SELECT *
FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY order_date DESC) AS row_num,
    order_id,
    customer_id,
    total_amount
  FROM orders
) AS temp
WHERE row_num BETWEEN 11 AND 20;
💡 Fetches page 2 (rows 11–20) without relying on database-specific pagination syntax.

⚖️ Comparison Table

Function Handles Ties Skips Ranks Great For
ROW_NUMBER() No (always unique) N/A Deterministic ordering, pagination
RANK() Yes Yes (1, 1, 3) Competition scoring, awarding prizes
DENSE_RANK() Yes No (1, 1, 2) Grouped ranking without gaps

💡 Interview Soundbite

“ROW_NUMBER is unique per row, RANK allows gaps for ties, and DENSE_RANK preserves continuity. Pick the function based on how you want to treat ties.”
← Back to Articles | 🏠 Back to Homepage