Under the Same Name

An easy SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
easy
Seniority
L3
Asked in
Vesta Innovations

Problem

An on-call engineer's latency breakdown of svc_health lists 'Healthy' and 'healthy' as two different states, because agents write the status in inconsistent letter casing. Treating every casing of a status as the same state, give the average check latency per status, slowest first.

The same state wears different casing. Read the latency behind each one.

Tables

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 4 of 4 rows
statusavg_latency
timeout401.1310344827586
degraded373.892
healthy353.31538461538463
unhealthy273.8121212121212

Worked solution and explanation

What this is really asking

This is a dirty-key cleanup dressed up as a latency report. The average is the easy part; the key is the trap. status in svc_health holds six spellings of four states ('healthy' and 'Healthy', 'degraded' and 'DEGRADED', plus 'unhealthy' and 'timeout'). Grouping on the raw column is case-sensitive, so it returns six rows. The 69 healthy checks split 39 and 30, the 59 degraded checks split 30 and 29, and every one of those averages covers only part of the evidence. Fold the casing before you aggregate and the six labels collapse into the four states the preview shows.

Break down the requirements

Step 1: Fold the casing in the key

Group on LOWER(status), not on status. That expression puts 'Healthy' and 'healthy' in one bucket. Project the same expression as the label, so each output row names one canonical, lowercase state and the label matches the grouping.

Step 2: Average each state

AVG(latency) skips the 23 checks with no latency recorded, so each mean covers only checks that were actually timed: 65 of the 69 healthy ones and 50 of the 59 degraded ones. Counting a missing latency as zero would pull every state's average down.

Step 3: Slowest first

Sort on avg_latency descending. 'timeout' leads at about 401 and 'unhealthy' trails at about 274. The four averages are all different, so the order needs no tie rule.

The solution

AVERAGE LATENCY BY NORMALIZED STATUS
SELECT
    LOWER(status) AS status,
    AVG(latency) AS avg_latency
FROM svc_health
GROUP BY LOWER(status)
ORDER BY avg_latency DESC
Raw label
GROUP BY status returns six rows. 'healthy' and 'Healthy' come back as separate states, and each is averaged over only the checks written with its own spelling.
Folded label
GROUP BY LOWER(status) returns four rows, one per real state. Each is averaged over every timed check of that state, whichever agent wrote it.

Common follow-up questions

Common follow-up questions