Fresh Ink

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
L3
Asked in
Spotify

Problem

Find the three repositories with the most commits in repo_commits, busiest first, for the platform team's review-staffing plan. The plan counts only recent work: commits dated in the month of the newest commit on record or in any of the 24 calendar months before it.

Recent activity is the only activity that counts. Name the busiest hands.

Tables

repo_commits

Columns: commit_id INTEGER, repo_name TEXT, author TEXT, message TEXT, added INTEGER, removed INTEGER, commit_at TEXT

repo_commits: 10 of 200 rows
commit_idrepo_nameauthormessageaddedremovedcommit_at
3061backend-apibobAdd unit tests1772026-02-02 01:09:00
3122infracharlieRefactor auth module34142026-03-03 02:18:00
3183ml-pipeline charlieUpdate deps51212026-04-04 03:27:00
3244mobile-appdana Improve perf68282026-05-05 04:36:00
3305data-platformfrank Add caching layer 85352026-06-06 05:45:00
3366frontendAliceFix typo in readme102422026-07-07 06:54:00
3427backend-apiBobNULL119492026-08-08 07:03:00
3488infraaliceWIP136562026-09-09 08:12:00
3549ml-pipelinebob153632026-01-10 09:21:00
3610mobile-appcharlieAdd search endpoint170702026-02-11 10:30:00

Expected output

First 3 of 3 rows
repo_namecommit_count
mobile-app26
ml-pipeline26
data-platform25

Worked solution and explanation

What this problem really is

This is a top three over a data-anchored month window, dressed up as a staffing question. Anyone can count commits per repo_name. What separates candidates is where the window starts and what type the year-month is when it gets compared. The cutoff is the newest commit's month, two years back, read off repo_commits itself. The row's year-month has to be a number at the comparison. Get that wrong and SQLite compares the text '202202' against the number 202409, decides text always wins, and every commit since 2022 sneaks in: four repositories tie at 34 and the real leaders at 26 never show.

Step 1: Read the cutoff off the data

(SELECT strftime('%Y%m', MAX(commit_at)) - 200 FROM repo_commits) returns 202409 on this seed. The '%Y%m' format packs year and month into one sortable number, so subtracting 200 steps back exactly two years to the same month: the newest month plus the 24 before it. The subtraction coerces the text on its own, so this side is already numeric.

Step 2: Make the row's year-month a number before comparing

strftime('%Y%m', commit_at) returns text. A comparison, unlike arithmetic, does not coerce: SQLite orders every text value above every integer, so '202202' >= 202409 is true. Wrapping the row side in CAST(... AS INTEGER) is the one conversion that changes the answer.

Step 3: Count every commit per repo_name

GROUP BY repo_name with COUNT(*). Some commits carry a NULL message, and COUNT(message) would quietly drop them. A commit is a row, not a message.

Step 4: Sort busiest first and keep three

ORDER BY commit_count DESC LIMIT 3 gives 'ml-pipeline' and 'mobile-app' at 26, then 'data-platform' at 25. The leaders tie, so either order is correct. The other three sit at 23, so the cut after third place is clean.

Data-anchored month window, numeric year-month, top three
SELECT repo_name, COUNT(*) AS commit_count
FROM repo_commits
WHERE CAST(strftime('%Y%m', commit_at) AS INTEGER) >=
      (SELECT strftime('%Y%m', MAX(commit_at)) - 200 FROM repo_commits)
GROUP BY repo_name
ORDER BY commit_count DESC
LIMIT 3
The version that looks right and keeps every row
SELECT repo_name, COUNT(*) AS commit_count
FROM repo_commits
WHERE strftime('%Y%m', commit_at) >=
      (SELECT strftime('%Y%m', MAX(commit_at)) - 200 FROM repo_commits)
GROUP BY repo_name
ORDER BY commit_count DESC
LIMIT 3

Without the cast, text beats number in every comparison: four repositories tie at 34.

Common follow-up questions