Healthiest Service Check History
A hard SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.
- Domain
- SQL
- Difficulty
- hard
- Seniority
- L4
- Asked in
- Vesta Innovations
Problem
We run scheduled health checks across a fleet of services, and every check logs an uptime score. Find the service or services whose uptime ever reached the highest value recorded anywhere in the table, and take that service's entire check history, not just its top-scoring checks. For every one of its checks show the check time, the time of the immediately preceding check, and the number of days between the two, and because the earliest check has nothing before it, keep that row too with its previous time and its gap left blank.
The healthiest service. Full history.
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 | checked | prev_checked | days_diff |
|---|---|---|---|
| cache-svc | 2023-01-09 12:12:00 | NULL | NULL |
| cache-svc | 2023-03-11 02:02:00 | 2023-01-09 12:12:00 | 60.57638888899237 |
| cache-svc | 2023-05-01 04:52:00 | 2023-03-11 02:02:00 | 51.118055555503815 |
| cache-svc | 2023-05-13 16:52:00 | 2023-05-01 04:52:00 | 12.5 |
| cache-svc | 2023-07-03 18:42:00 | 2023-05-13 16:52:00 | 51.07638888899237 |
Worked solution and explanation
This is a gap-between-consecutive-rows problem hiding behind a service-health leaderboard. There are two moves. First, a global aggregate picks the group: the single highest uptime ever recorded, and every service that touched it. Second, an ordered window walks each chosen service's full timeline. Most candidates get the LAG roughly right. The failure is almost always in the first move. ORDER BY uptime DESC LIMIT 1 quietly keeps one co-champion and deletes the other's entire history, so whole blocks of expected rows vanish and nothing errors.
The trap
- Looks right
ORDER BY uptime DESC LIMIT 1returns one row, so one service. A per-serviceMAX(uptime)goes wrong the other way and admits every service. SubtractingDATE(checked)values turns a gap of 79.59 days into 79 or 80.- Actually right
uptime = (SELECT MAX(uptime) FROM svc_health)keeps every service tied at the global max.JULIANDAYon the fullcheckedtimestamp keeps the fractional day.
Building it
Step 1: Gate on the global max, ties included
The scalar subquery (SELECT MAX(uptime) FROM svc_health) is computed once over the whole table. Filtering on equality with it and applying SELECT DISTINCT svc_name gives a small set of names in healthiest. If two services share the top score, both appear in that set.
Step 2: Take the whole history, not the winning rows
The outer query filters on s.svc_name IN (SELECT svc_name FROM healthiest) and does not filter on uptime. The prompt asks for every check the champion ever logged. Filtering on uptime a second time would shrink each history to its top-scoring checks.
Step 3: Walk each timeline with LAG
LAG(s.checked) OVER (PARTITION BY s.svc_name ORDER BY s.checked) returns the check immediately before the current one within the same service. The query contains two LAG calls. Because both use an identical window, the engine sorts once and evaluates the window a single time.
Step 4: Let the first check stay NULL
The earliest check in each partition has nothing before it, so LAG returns NULL and JULIANDAY(NULL) also yields NULL. The row stays in the output with blank prev_checked and days_diff, which is what the prompt asks for. Adding WHERE prev_checked IS NOT NULL would drop one correct row per service.
WITH healthiest AS (
SELECT DISTINCT svc_name
FROM svc_health
WHERE uptime = (SELECT MAX(uptime) FROM svc_health)
)
SELECT
s.svc_name,
s.checked,
LAG(s.checked) OVER (PARTITION BY s.svc_name ORDER BY s.checked) AS prev_checked,
JULIANDAY(s.checked)
- JULIANDAY(LAG(s.checked) OVER (PARTITION BY s.svc_name ORDER BY s.checked)) AS days_diff
FROM svc_health s
WHERE s.svc_name IN (SELECT svc_name FROM healthiest)One global MAX, one shared window, fractional-day gaps.
Common follow-up questions
- Checks should fire every 15 minutes. How would you flag rows where `days_diff` exceeds that cadence? (Filtering on a window result requires wrapping the query, because `WHERE` runs before the window is evaluated.)
- Two checks share the same `checked` timestamp. What does `LAG` return, and how do you make the result deterministic? (Tests tie-breaking inside `ORDER BY`, for example by adding `check_id`.)
- Only the last 30 days matter. Where does the date bound go, and does it change which service wins? (A bound on the outer query prunes partitions without changing the winner. A bound on the `MAX` subquery changes the question being answered.)