runtime
36 / 88

lesson 36 Window functions · advanced

RANK & DENSE_RANK

Rank rows and decide how ties should behave.

the idea

RANK gives ties the same rank, then leaves a gap. DENSE_RANK gives ties the same rank without gaps. ROW_NUMBER always assigns distinct numbers.

tables in this lesson

The challenges use this data. Each column shows its type underneath; → marks a link to another table.

orders6 columns · 12 rows
idinteger · keycustomer_idintegerproduct_idintegerquantityintegerstatustextordered_attext
101112paid2025-01-01
102231paid2025-01-02
103121paid2025-01-05
104352pending2025-01-08
105445paid2025-02-01

showing 5 of 12 rows

example

The idea in one query. Press Run to see what it returns; running examples never affects your progress.

example.sql
SELECT
  customer_id,
  COUNT(*) AS order_count,
  DENSE_RANK() OVER(ORDER BY COUNT(*) DESC) AS rank
FROM orders
GROUP BY customer_id;

Watch for: Ties exist in this dataset, so RANK and DENSE_RANK produce different outputs.

build it step by step

Each step changes one thing. Run them in order and watch the result change.

  1. Measure the value you will rank. Ranking needs a sort key. Count orders per customer first; DENSE_RANK will order those counts.

    step-1.sql
    SELECT customer_id, COUNT(*) AS order_count
    FROM orders
    GROUP BY customer_id
    ORDER BY order_count DESC, customer_id;
  2. Assign dense ranks to groups. DENSE_RANK gives the same rank to ties and does not skip the next rank. RANK would leave gaps after ties.

    step-2.sql
    SELECT
      customer_id,
      COUNT(*) AS order_count,
      DENSE_RANK() OVER(ORDER BY COUNT(*) DESC) AS rank
    FROM orders
    GROUP BY customer_id;

challenge 1

Show customer_id, order_count and rank using DENSE_RANK by order_count descending.

Return customer_idorder_countrankany row order

challenge-1.sql
 
To master this lesson, solve both challenges without hints and pass the concept check. 3 of 3 to go.