Busy Authors

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

Problem

An engineering manager is spotlighting the most prolific contributors, leaving out any commit whose message was never recorded (a blank message still counts). For each author credited with 24 or more of the remaining commits, show their commit total and how many repositories they've touched.

Some developers spread their commits everywhere.

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 4 of 4 rows
authorcommit_countrepo_count
alice443
bob463
charlie254
dana244

Worked solution and explanation

The skill hiding under the commit log

This is an identity-folding aggregation with a data-quality filter, wearing a 'who is most active' costume. Two things have to happen before you count anything. First, fold each developer's case-variant names into one person: the author column was never normalized on write, so 'Alice' and 'alice' are one human typed two ways, and if you group on the raw column her 44 commits split into two piles of 22 that both fall under the cutoff, so your busiest engineer silently vanishes from the standings. Second, drop the commits whose message was never recorded (message IS NULL), since those are not tallyable work, while a blank empty-string message is still a genuine commit that counts. Fold, filter, then count.


Walking the query

Step 1: Fold the identity

Group by LOWER(TRIM(author)) so every casing (and any stray whitespace) of a name lands in one bucket. This is the decision the whole problem turns on: GROUP BY author scatters bob across 'bob' and 'Bob', so his real total of 46 never appears; GROUP BY LOWER(TRIM(author)) recovers the true contributors.

Step 2: Drop the never-recorded commits

The manager only wants commits that were actually logged with a message, so filter WHERE message IS NOT NULL. Watch the NULL-versus-blank distinction: a NULL message means nothing was ever recorded and is dropped, but an empty-string message ('') is a real if terse commit and stays. Reaching for TRIM(message) <> '' here would wrongly delete the blank commits too, and your totals would come out too low.

Step 3: Count two different things

COUNT(*) is raw commit volume (how busy the person is). COUNT(DISTINCT repo_name) is spread (how many separate codebases they touched). These are not the same number: bob has 46 commits across only 3 repos. The prompt asks for both, so compute both.

Step 4: Filter after aggregating

The '24 or more commits' cutoff is a property of the whole group, not of any single commit row, so it belongs in HAVING COUNT(*) >= 24, which runs after the grouping. A WHERE cannot see a group-level count.

Step 5: Order the standings

Busiest first is commit_count DESC. Equal totals (charlie, dana and eve all land on 24) settle alphabetically by author so the ordering is stable and repeatable rather than whatever the engine happens to emit.

The solution

Prolific contributors, case-folded and message-filtered
SELECT LOWER(TRIM(author)) AS author,
       COUNT(*) AS commit_count,
       COUNT(DISTINCT repo_name) AS repo_count
FROM repo_commits
WHERE message IS NOT NULL
GROUP BY LOWER(TRIM(author))
HAVING COUNT(*) >= 24
GROUP BY author (raw)
bob splits into 'bob' (24) and 'Bob' (22), alice into 'alice' (22) and 'Alice' (22). The 22s fall under the cutoff, so the two busiest engineers are cut down and the standings name the wrong people.
GROUP BY LOWER(TRIM(author))
Every spelling folds into one contributor: bob 46, alice 44. Five real people, correctly ranked, with charlie, dana and eve tied at 24.

Common follow-up questions