Repos with More Builds Than Commits
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
- L4
Problem
Looking at CI/CD health, find all repos where the number of builds meets or exceeds the number of commits. Show each repo with its build count, ranked from highest to lowest.
More builds than commits. Something is off.
Tables
ci_builds
Columns: build_id INTEGER, repo_name TEXT, branch TEXT, status TEXT, dur_secs INTEGER, trigger TEXT, built_at TEXT
| build_id | repo_name | branch | status | dur_secs | trigger | built_at |
|---|---|---|---|---|---|---|
| 5047 | backend-api | develop | failed | 34 | pull_request | 2026-02-02 01:13:00 |
| 5094 | infra | feature/auth | canceled | 53 | schedule | 2026-03-03 02:26:00 |
| 5141 | ml-pipeline | fix/login-bug | running | 72 | manual | 2026-04-04 03:39:00 |
| 5188 | mobile-app | release/v2.0 | queued | 91 | tag | 2026-05-05 04:52:00 |
| 5235 | data-platform | hotfix/payment | success | 110 | webhook | 2026-06-06 05:05:00 |
| 5282 | frontend | feature /spaces | failed | NULL | push | 2026-07-07 06:18:00 |
| 5329 | backend-api | main | canceled | 148 | pull_request | 2026-08-08 07:31:00 |
| 5376 | infra | develop | running | 167 | schedule | 2026-09-09 08:44:00 |
| 5423 | ml-pipeline | feature/auth | queued | 186 | manual | 2026-01-10 09:57:00 |
| 5470 | mobile-app | fix/login-bug | success | 205 | tag | 2026-02-11 10:10:00 |
repo_commits
Columns: commit_id INTEGER, repo_name TEXT, author TEXT, message TEXT, added INTEGER, removed INTEGER, commit_at TEXT
| commit_id | repo_name | author | message | added | removed | commit_at |
|---|---|---|---|---|---|---|
| 3061 | backend-api | bob | Add unit tests | 17 | 7 | 2026-02-02 01:09:00 |
| 3122 | infra | charlie | Refactor auth module | 34 | 14 | 2026-03-03 02:18:00 |
| 3183 | ml-pipeline | charlie | Update deps | 51 | 21 | 2026-04-04 03:27:00 |
| 3244 | mobile-app | dana | Improve perf | 68 | 28 | 2026-05-05 04:36:00 |
| 3305 | data-platform | frank | Add caching layer | 85 | 35 | 2026-06-06 05:45:00 |
| 3366 | frontend | Alice | Fix typo in readme | 102 | 42 | 2026-07-07 06:54:00 |
| 3427 | backend-api | Bob | NULL | 119 | 49 | 2026-08-08 07:03:00 |
| 3488 | infra | alice | WIP | 136 | 56 | 2026-09-09 08:12:00 |
| 3549 | ml-pipeline | bob | 153 | 63 | 2026-01-10 09:21:00 | |
| 3610 | mobile-app | charlie | Add search endpoint | 170 | 70 | 2026-02-11 10:30:00 |
Expected output
| repo_name | build_count |
|---|---|
| mobile-app | 34 |
| ml-pipeline | 34 |
| infra | 34 |
| frontend | 32 |
| data-platform | 32 |
Worked solution and explanation
Why this problem exists in real interviews
The core skill being tested is self-join, applied to the ci_builds and repo_commits tables in a analytics context. Getting columns like build_id, repo_name, and commit_id right is where most candidates slip. The problem layers in HAVING for post-aggregation filtering as well.
Break down the requirements
Step 1: Join ci_builds to repo_commits
The join connects the two tables on their shared key. This brings the columns needed for filtering and aggregation into a single row set.
Step 2: Deduplicate the result with DISTINCT
SELECT DISTINCT removes duplicate rows from the output. This is necessary when joins or subqueries can produce repeated combinations.
The solution
SELECT cb.repo_name, COUNT(DISTINCT cb.build_id) AS build_count
FROM ci_builds cb
INNER JOIN repo_commits rc ON cb.repo_name = rc.repo_name
GROUP BY cb.repo_name
HAVING COUNT(DISTINCT cb.build_id) >= COUNT(DISTINCT rc.commit_id)
ORDER BY build_count DESCCommon follow-up questions
- The `dur_secs` column in `ci_builds` has a 2% null rate. How does your query handle rows where `dur_secs` is NULL, and could that silently change the result count? (Tests whether the candidate accounts for NULLs in `ci_builds.dur_secs` and understands how aggregates skip NULL values.)
- If `repo_commits` grew to contain billions of rows, which part of your query would become the bottleneck given the cardinality of `message`? (Tests ability to identify performance hotspots related to `repo_commits.message` at scale.)
- If the HAVING threshold in your query changed from a fixed number to a percentile, how would you restructure the query? (Tests ability to replace static HAVING filters with dynamic subquery-based thresholds.)