Single Service Owners
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
- Vesta Innovations
Problem
List the services whose checks in svc_health came from exactly two different regions, each with that region count and its average checks per region as an exact decimal (seven checks over two regions is 3.5), alphabetically and stopping at the first five. The reliability team's audit only counts checks logged since the start of 2024.
One owner, one service. Nobody else.
Tables
svc_health
Columns: check_id INTEGER, svc_name TEXT, status TEXT, latency REAL, uptime REAL, checked TEXT, region TEXT
| check_id | svc_name | status | latency | uptime | checked | region |
|---|---|---|---|---|---|---|
| 137 | payment-api | degraded | 3.6 | 97.03 | 2026-02-02 01:05:00 | us-west-2 |
| 174 | user-svc | unhealthy | 6.7 | 94.06 | 2026-03-03 02:10:00 | eu-west-1 |
| 211 | search-api | timeout | 9.8 | 91.09 | 2026-04-04 03:15:00 | ap-south-1 |
| 248 | gateway | Healthy | 12.9 | 98.12 | 2026-05-05 04:20:00 | eu-central-1 |
| 285 | notif-svc | DEGRADED | 16 | 95.15 | 2026-06-06 05:25:00 | us-east-1 |
| 322 | ml-serving | healthy | 19.1 | 92.18 | 2026-07-07 06:30:00 | us-west-2 |
| 359 | cache-svc | degraded | NULL | 99.21 | 2026-08-08 07:35:00 | eu-west-1 |
| 396 | queue-worker | unhealthy | 25.3 | 96.24 | 2026-09-09 08:40:00 | ap-south-1 |
| 433 | cron-svc | timeout | 28.4 | 93.27 | 2026-01-10 09:45:00 | eu-central-1 |
| 470 | auth-svc | Healthy | 31.5 | 90.3 | 2026-02-11 10:50:00 | us-east-1 |
Expected output
| svc_name | region_count | checks_per_region |
|---|---|---|
| auth-svc | 2 | 9 |
| cron-svc | 2 | 9 |
| gateway | 2 | 9 |
| notif-svc | 2 | 9 |
| queue-worker | 2 | 9 |
Worked solution and explanation
What this is really asking
Strip the audit costume and this is a regional-footprint measurement fenced inside a time window, with a type question hiding in the last column. Anyone can write the GROUP BY. What separates candidates is whether the footprint is the number of different region values rather than the number of check rows, and whether the per-region average survives division intact. COUNT(*) / COUNT(DISTINCT region) divides two integers, and integer division throws the remainder away: seven checks over two regions reports 3, not 3.5. Count rows and the narrow services vanish; skip the cast and every odd-count service ships a quietly wrong average.
Working through it
Step 1: Prune to the recent window
The audit only cares about checks from the start of 2024 onward, so WHERE checked >= '2024-01-01' runs before any counting. Both output numbers depend on it: older checks would add regions to the footprint and rows to the average.
Step 2: Aggregate by svc_name
GROUP BY svc_name collapses the surviving checks to one row per service, so every aggregate is computed across that service's recent checks only.
Step 3: Count distinct regions, not checks
Reach is COUNT(DISTINCT region), not COUNT(*). A service checked 18 times in 2 regions has a raw count of 18 and a region count of 2. Only the distinct count answers 'how many regions'.
Step 4: Make the average exact
Divide the check count by the region count, but make one side a decimal first with CAST(COUNT(*) AS REAL). Two integers divide to an integer in most SQL engines, so without the cast every odd total loses its half.
Step 5: Filter the aggregate, order, cap
HAVING COUNT(DISTINCT region) = 2 keeps the narrow services; it must be HAVING because the count does not exist until after grouping. ORDER BY svc_name is deterministic since names are unique per group, and LIMIT 5 drops the sixth qualifier.
The solution
SELECT svc_name,
COUNT(DISTINCT region) AS region_count,
CAST(COUNT(*) AS REAL) / COUNT(DISTINCT region) AS checks_per_region
FROM svc_health
WHERE checked >= '2024-01-01'
GROUP BY svc_name
HAVING COUNT(DISTINCT region) = 2
ORDER BY svc_name
LIMIT 5- Uncast
COUNT(*) / COUNT(DISTINCT region)with 7 checks and 2 regions returns 3. No error, no warning, just a smaller number.- Cast
CAST(COUNT(*) AS REAL) / COUNT(DISTINCT region)returns 3.5. Casting either operand promotes the whole division to decimal.
Common follow-up questions
- How would you widen this to services covering two or three regions? (Moves an equality threshold to a range in `HAVING`.)
- If the dashboard wanted the average to two decimal places, where would you round, and why not earlier? (Probes rounding as a presentation choice versus exact storage.)
- If some checks had a `NULL` `region`, how would that change each column? (Probes NULL handling inside `COUNT(DISTINCT region)` and `COUNT(*)`.)