Latest Version Per Service
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
- Meta
Problem
The release dashboard has been skipping every deploy that went to staging or failed, and the on-call engineer found services stuck on builds they have since moved past. Rebuild it from deploy_logs: each service with the version from its most recent deploy and how many seconds that deploy ran.
The latest version deployed. Each service.
Tables
deploy_logs
Columns: log_id INTEGER, svc_name TEXT, version TEXT, env_name TEXT, status TEXT, deploy_at TEXT, dur_secs INTEGER, author TEXT
| log_id | svc_name | version | env_name | status | deploy_at | dur_secs | author |
|---|---|---|---|---|---|---|---|
| 131 | payment-api | v1.0.2 | staging | failed | 2026-02-02 01:11:00 | 23 | bob |
| 162 | user-svc | v1.1.0 | dev | rolled_back | 2026-03-03 02:22:00 | 36 | charlie |
| 193 | search-api | 2.0.0 | canary | in_progress | 2026-04-04 03:33:00 | 49 | dana |
| 224 | gateway | v2.1.0 | Production | Success | 2026-05-05 04:44:00 | 62 | eve |
| 255 | notif-svc | 2.1.1 | STAGING | FAILED | 2026-06-06 05:55:00 | 75 | frank |
| 286 | analytics | v3.0.0-rc1 | production | success | 2026-07-07 06:06:00 | 88 | Alice |
| 317 | ml-serving | v1.0.3 | staging | failed | 2026-08-08 07:17:00 | NULL | BOB |
| 348 | auth-svc | v1.0.1 | dev | Rolled_Back | 2026-09-09 08:28:00 | 114 | alice |
| 379 | Payment-API | v1.0.2 | canary | in_progress | 2026-01-10 09:39:00 | 127 | bob |
| 410 | user-svc | v1.1.0 | Production | Success | 2026-02-11 10:50:00 | 140 | charlie |
Expected output
| svc_name | version | dur_secs |
|---|---|---|
| payment-api | v1.0.2 | 231 |
| Payment-API | v1.0.2 | 127 |
| analytics | v3.0.0-rc1 | 216 |
| auth-svc | v1.0.1 | 114 |
| gateway | v2.1.0 | 582 |
Worked solution and explanation
What this really is
This is a latest-row-per-group lookup dressed up as a release dashboard. Finding when each service last deployed is one MAX(deploy_at); the skill is getting the version and the duration out of that same row. Anyone can write the GROUP BY. What separates candidates is noticing that MAX(dur_secs) beside it reports the service's slowest deploy ever, not its latest, so the dashboard quietly stitches together numbers from different deploys.
Walking to the answer
Step 1: Keep every deploy in scope
The broken dashboard dropped staging and failed deploys, which is exactly why services looked stuck. No WHERE on env_name or status: a failed rollout to staging is still the last thing that touched the service, and you also avoid the mixed casing ('Production', 'STAGING', 'FAILED') those columns carry.
Step 2: Number each service's deploys by deploy_at, newest first
ROW_NUMBER() OVER (PARTITION BY svc_name ORDER BY deploy_at DESC) restarts the count for every service and gives 1 to its newest deploy. deploy_at is a fixed-width 'YYYY-MM-DD HH:MM:SS' string, so descending text order is newest-first time order.
Step 3: Keep number one in the outer query
Filter ranked_deploys to recency = 1. A window result does not exist yet when the same SELECT's WHERE runs, which is why the numbering sits in a derived table and the filter one level up.
SELECT svc_name, version, dur_secs
FROM (
SELECT svc_name, version, dur_secs,
ROW_NUMBER() OVER (PARTITION BY svc_name ORDER BY deploy_at DESC) AS recency
FROM deploy_logs
) ranked_deploys
WHERE recency = 1One numbered pass over deploy_logs; version and dur_secs both come from the row numbered 1.
- Summarize each column
SELECT svc_name, MAX(version), MAX(dur_secs) ... GROUP BY svc_nameruns and returns one row per service, which is why it looks right.MAX(dur_secs)is the slowest deploy the service ever had, andMAX(version)is the alphabetically largest string, so 'v3.0.0-rc1' would outrank '2.1.1' whenever both appeared.- Pick the newest row
ranked_deployskeeps exactly one row per service, the one with the latestdeploy_at, andversionanddur_secsare both read from it.
Common follow-up questions
- Two deploys of the same service land on the same `deploy_at`: which one should the dashboard show, and how do you make that choice repeatable? (Tests adding a deterministic tie-breaker such as `log_id` to the window's `ORDER BY`.)
- 'Payment-API' and ' payment-api' show up as separate rows. How would you fold them into one service? (Tests normalizing a dirty key with `TRIM` and `LOWER` before partitioning.)
- The dashboard now also needs the latest successful production deploy per service. What changes? (Tests a case-insensitive filter on `env_name` and `status` before numbering, alongside the unfiltered result.)