The Blast Radius

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
Google

Problem

Find each author's average latency score, rounded to two decimals and highest first, where every svc_health check logged for a service counts as one score for each deploy_logs deploy of that same service. The release-engineering team's scoreboard carries one row per person, however their name happened to be typed on the deploy record.

A reliability scoreboard for deploy teams.

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

deploy_logs: 10 of 200 rows
log_idsvc_nameversionenv_namestatusdeploy_atdur_secsauthor
131payment-apiv1.0.2stagingfailed2026-02-02 01:11:0023bob
162user-svcv1.1.0devrolled_back2026-03-03 02:22:0036charlie
193search-api2.0.0canaryin_progress2026-04-04 03:33:0049dana
224gatewayv2.1.0ProductionSuccess2026-05-05 04:44:0062eve
255notif-svc2.1.1STAGINGFAILED2026-06-06 05:55:0075frank
286analyticsv3.0.0-rc1productionsuccess2026-07-07 06:06:0088Alice
317ml-servingv1.0.3stagingfailed2026-08-08 07:17:00NULLBOB
348auth-svcv1.0.1devRolled_Back2026-09-09 08:28:00114alice
379Payment-APIv1.0.2canaryin_progress2026-01-10 09:39:00127bob
410user-svcv1.1.0ProductionSuccess2026-02-11 10:50:00140charlie

svc_health

Columns: check_id INTEGER, svc_name TEXT, status TEXT, latency REAL, uptime REAL, checked TEXT, region TEXT

svc_health: 10 of 200 rows
check_idsvc_namestatuslatencyuptimecheckedregion
137payment-apidegraded3.697.032026-02-02 01:05:00us-west-2
174user-svcunhealthy6.794.062026-03-03 02:10:00eu-west-1
211search-apitimeout9.891.092026-04-04 03:15:00ap-south-1
248gatewayHealthy12.998.122026-05-05 04:20:00eu-central-1
285notif-svcDEGRADED1695.152026-06-06 05:25:00us-east-1
322ml-servinghealthy19.192.182026-07-07 06:30:00us-west-2
359cache-svcdegradedNULL99.212026-08-08 07:35:00eu-west-1
396queue-workerunhealthy25.396.242026-09-09 08:40:00ap-south-1
433cron-svctimeout28.493.272026-01-10 09:45:00eu-central-1
470auth-svcHealthy31.590.32026-02-11 10:50:00us-east-1

Expected output

First 5 of 6 rows
authoravg_score
eve385.42
alice381.49
frank379.86
bob372.76
dana361.85

Worked solution and explanation

What this really is

This is a many-to-many fan-out feeding an average, with a dirty grouping key on top. Anyone can write the join and the AVG. What separates candidates is noticing two things before the query runs: svc_name is not a key on either side, so one deploy drags in every health check its service ever logged, and author stores the same human as 'Alice', 'alice' and 'BOB'. Group on the raw name and one person fractures into several rows, each holding a partial average, and the scoreboard lists people who do not exist.


Working through it

Step 1: Match deploys to their health checks

Join deploy_logs to svc_health on svc_name so each deploy lines up with its service's health checks. Say out loud that this is many-to-many: roughly 100 services on both sides means one deploy_logs row can explode into thousands of joined rows.

Step 2: Average latency and round it

Each matched svc_health row contributes its latency as one score, and a NULL reading simply drops out of AVG. The average spans every check attached to every deploy the author shipped, which is what the prompt defines, even though it over-weights busy services. Wrap it in ROUND(..., 2): the raw value carries float tails like 381.48749999 that will never match a two-decimal scoreboard.

Step 3: Fold case variants with LOWER()

The expected output shows only lowercase names, while the input holds 'Alice', 'alice', 'BOB' and 'bob'. Group and select on LOWER(dl.author) in both places, or the grain splits and every average lands on a fragment of a person.

Step 4: Order by avg_score, highest first

ORDER BY avg_score DESC puts the highest average on top. Every author lands on a different rounded avg_score here, so the single key is already a total order; add an author tiebreaker the day two people can tie.


The solution

Cross-table average with case-folded authors
SELECT
    LOWER(dl.author) AS author,
    ROUND(AVG(sh.latency), 2) AS avg_score
FROM deploy_logs dl
JOIN svc_health sh ON dl.svc_name = sh.svc_name
GROUP BY LOWER(dl.author)
ORDER BY avg_score DESC

Common follow-up questions