Service Reliability Tiers
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
- Asked in
- Airbnb
Problem
Checks taken while a service was flagged as degraded carry distorted latency and stay out of the numbers. Every other check falls into a reliability tier by its uptime: 99.9% and up is 'Platinum', 99.0 to 99.89% is 'Gold', 95.0 to 98.99% is 'Silver', and anything lower, or with no uptime recorded, is 'Bronze'. Report each tier's minimum, average, and maximum latency, highest average latency first.
Reliability tiers. Based on uptime.
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
| tier | min_latency | avg_latency | max_latency |
|---|---|---|---|
| Gold | 84.2 | 483.40000000000003 | 792.3 |
| Bronze | 6.7 | 386.280303030303 | 816.9 |
| Silver | 12.9 | 265.1730769230769 | 804.6 |
Worked solution and explanation
What this really is
Strip the monitoring costume and this is a bucket-then-summarize with a poison-row filter hiding in the WHERE. Anyone can write the CASE ladder and the MIN/AVG/MAX. What separates candidates is the exclusion. Degraded checks carry distorted latency, and status stores them in two casings, 'degraded' and 'DEGRADED'. String comparison here respects case, LIKE included, so status != 'degraded' or a lone NOT LIKE 'degraded%' quietly keeps every uppercase row. Those readings flow into the tier numbers: Gold's minimum drops from 84.2 to 53.2, its average sinks by about 70, and nothing about the result looks wrong.
Working to the answer
Step 1: Derive the tier from uptime
No column stores the tier, so you derive it. A CASE ladder over uptime checks the highest cutoff first and falls through. Each branch uses >=, so a service at exactly 99.0 lands in 'Gold', not 'Silver'. The ELSE does real work too. A check whose uptime is NULL matches no branch and falls to 'Bronze', which is what the statement asks for. Dropping those rows is a different answer.
Step 2: Exclude degraded checks in every casing
Read the sample rows before writing the filter: 'degraded' and 'DEGRADED' both appear, and so do 'healthy' and 'Healthy'. Comparisons here are case-sensitive, so one pattern catches one spelling. Exclude both with status NOT LIKE 'degraded%' AND status NOT LIKE 'DEGRADED%', and put that in the WHERE so the poisoned rows never reach an aggregate.
Step 3: Summarize latency per tier
GROUP BY the tier alias and take MIN, AVG and MAX of latency per group. NULL latencies need no handling: aggregates skip NULL, so they are neither counted nor treated as zero. Adding COALESCE(latency, 0) would drag the average down.
Step 4: Order by average latency
The result reads worst-first, so ORDER BY avg_latency DESC puts the most latent tier on top. Sort on the computed average, not on a raw column.
The solution
SELECT
CASE
WHEN uptime >= 99.9 THEN 'Platinum'
WHEN uptime >= 99.0 THEN 'Gold'
WHEN uptime >= 95.0 THEN 'Silver'
ELSE 'Bronze'
END AS tier,
MIN(latency) AS min_latency,
AVG(latency) AS avg_latency,
MAX(latency) AS max_latency
FROM svc_health
WHERE status NOT LIKE 'degraded%'
AND status NOT LIKE 'DEGRADED%'
GROUP BY tier
ORDER BY avg_latency DESC- Leaks the uppercase rows
status != 'degraded',status NOT IN ('degraded')and a loneNOT LIKE 'degraded%'each match one spelling. Every 'DEGRADED' check stays in its tier.- Covers both spellings
status NOT LIKE 'degraded%' AND status NOT LIKE 'DEGRADED%'removes each casing the data holds, so only clean checks reachMIN,AVGandMAX.
Common follow-up questions
- `latency` is about 1% NULL. How does your query treat those rows across `MIN`, `AVG` and `MAX`, and would `COALESCE(latency, 0)` change the answer? (Tests whether the candidate knows aggregates skip NULLs in `svc_health.latency` rather than counting them.)
- Next week a check arrives with `status` 'Degraded'. Your filter lists two spellings. How would you make the exclusion hold for any casing, and where would you fix it upstream? (Tests case normalization with `LOWER`, engine-dependent `LIKE` semantics and normalizing data on write.)
- A service reports `uptime` of exactly 99.0. Which tier does it land in? How would you change the ladder to put it in 'Silver', and to report checks with no uptime separately? (Tests boundary reasoning and NULL handling on the `CASE` ladder.)