Top Lessons Each Month

A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
medium
Seniority
L5
Asked in
Walmart

Problem

Walking the calendar from the earliest month forward, surface the three most-completed lessons in each month, most completions first, and let the page address break the tie alphabetically whenever two lessons finished level. The content team uses this to guide investment decisions for the next quarter.

Rank items within time periods and keep top 3

Tables

page_views

Columns: view_id INTEGER, page_url TEXT, user_id INTEGER, referrer TEXT, dur_ms INTEGER, device TEXT, viewed_at TEXT

page_views: 10 of 200 rows
view_idpage_urluser_idreferrerdur_msdeviceviewed_at
5053/products1555amazon.com637desktop2026-09-02 01:09:00
5106/checkout1652twitter.com774tablet2026-09-03 02:18:00
5159/profile1749github.com911Mobile2026-09-04 03:27:00
5212/search1846NULL1048DESKTOP2026-09-05 04:36:00
5265/about1943reddit.com1185mobile2026-09-06 05:45:00
5318/blog/intro1555NULLNULLdesktop2026-09-07 06:54:00
5371/pricing1652bing.com1459tablet2026-09-08 07:03:00
5424/docs/api1749news.ycombinator.com1596Mobile2026-09-09 08:12:00
5477/settings1846NULL1733DESKTOP2026-09-10 09:21:00
5530/Home1943bing.com1870mobile2026-09-11 10:30:00

Expected output

First 5 of 142 rows
monthpage_urlcompletion_countrank
2022-01/about11
2022-01/products11
2022-02/checkout11
2022-02new_editor11
2026-01/checkout21

Worked solution and explanation

Why this problem exists in real interviews

Notice the gap: the prompt asks about lesson completions, the table is page_views. A row here is a view, not a completion. In a real review you would push for a lesson_completions event source. For this exercise, page_url stands in as the lesson identifier and every row counts as a completion, which is the simplification the query bakes in.


Break down the requirements

Step 1: Bucket views into months

strftime('%Y-%m', viewed_at) returns a sortable text label per month. Aggregating to (month, page_url) collapses 500M rows into a small set keyed by lesson and month.

Step 2: Rank within each month

RANK() OVER (PARTITION BY month ORDER BY completion_count DESC) resets per month. Two lessons tied for second both get rank 2; rank 3 still exists. The next position is 4, not 3.

Step 3: Filter to the top three and order for the consumer

WHERE rnk <= 3 keeps the top tier. The outer ORDER BY month, rnk produces the calendar walk the content team expects to read.


The solution

TOP LESSONS EACH MONTH
WITH monthly AS (
  SELECT strftime('%Y-%m', viewed_at) AS month,
         page_url,
         COUNT(*) AS completion_count
  FROM page_views
  GROUP BY 1, 2
),
ranked AS (
  SELECT month,
         page_url,
         completion_count,
         RANK() OVER (PARTITION BY month ORDER BY completion_count DESC) AS rnk
  FROM monthly
)
SELECT month, page_url, completion_count, rnk AS rank
FROM ranked
WHERE rnk <= 3
ORDER BY month, rnk, page_url

COMMON FOLLOW-UP QUESTIONS

Common follow-up questions