Build Success vs Failure by Repo
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
- Tesla
Problem
The engineering lead needs a per-repo build health snapshot before freezing deploys. For each repository, show how many builds have a status of 'success', how many have a status of 'failure', and the average build duration.
Green versus red, repo by repo.
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 |
Expected output
| repo_name | success_count | failure_count | avg_duration |
|---|---|---|---|
| backend-api | 6 | 0 | 416.5882352941176 |
| data-platform | 8 | 0 | 458.75 |
| frontend | 6 | 0 | NULL |
| infra | 6 | 0 | 435.5882352941176 |
| mobile-app | 8 | 0 | 473.5882352941176 |
Worked solution and explanation
What this is really asking
status carries more than two values (success, failure, plus running, canceled, timeout), but avg_duration is over every build. The conditional aggregation has to count two values and average across all of them in one pass.
Break down the requirements
Step 1: Group once per repo
Single GROUP BY repo_name over the 3M row table. Every metric lives in the same aggregate, no joins or subqueries.
Step 2: Branch the counts with CASE
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) and the mirror for 'failure'. The ELSE 0 keeps in-flight and canceled builds in the table without inflating either count.
Step 3: Average duration over everything
AVG(dur_secs) runs across all statuses for the repo. No WHERE clause filters them out; the engineering lead wants total throughput, not just terminal builds.
The solution
SELECT repo_name,
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS success_count,
SUM(CASE WHEN status = 'failure' THEN 1 ELSE 0 END) AS failure_count,
AVG(dur_secs) AS avg_duration
FROM ci_builds
GROUP BY repo_name
;COMMON FOLLOW-UP QUESTIONS
Common follow-up questions
- How would you add a success rate column? (Divide `success_count` by `COUNT(*)` or by `(success_count + failure_count)` depending on whether in-flight builds belong in the denominator; cast to a decimal to avoid integer division.)
- What if the lead only cares about the main branch? (Add `WHERE branch = 'main'` before the GROUP BY; the conditional aggregation pattern stays unchanged and still handles every status.)
- How would you flag repos where the failure count tripled week over week? (Add `DATE_TRUNC('week', built_at)` to the grouping, then `LAG(failure_count)` partitioned by repo ordered by week and filter where the ratio exceeds three.)