Where the Signal Drops

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
mid
Asked in
Verizon

Problem

On-call has been tracking API reliability and wants to know which endpoints are failing most often. Look only at endpoints with at least 20 calls, and for each one report its share of error responses (a 4xx or 5xx status), worst first.

Every endpoint answers. Some just answer wrong. Find the ones dropping the most.

Tables

api_calls

Columns: call_id INTEGER, endpoint TEXT, method TEXT, status INTEGER, latency REAL, user_id INTEGER, call_time TEXT, err_msg TEXT

api_calls: 10 of 670 rows
call_idendpointmethodstatuslatencyuser_idcall_timeerr_msg
8079/api/v1/ordersPOST2004.21002026-02-02 01:07:00NULL
8158/api/v2/productsPUT2007.91972026-03-03 02:14:00NULL
8237/api/v1/searchDELETE20111.62942026-04-04 03:21:00NULL
8316/api/v1/auth/loginPATCH20415.33912026-05-05 04:28:00NULL
8395/api/v1/auth/logoutget30119NULL2026-06-06 05:35:00NULL
8474/api/v2/analyticspost40022.75852026-07-07 06:42:00Not found
8553/api/v1/paymentsGET40126.46822026-08-08 07:49:00Unauthorized
8632/api/v1/users/POST40330.17792026-09-09 08:56:00Rate limit exceeded
8711/api/v2/products/PUT40433.88762026-01-10 09:03:00Internal server error
8790/api/v1/usersDELETE50037.5NULL2026-02-11 10:10:00Bad gateway

Expected output

First 5 of 7 rows
endpointtotal_callserror_callserror_rate
/api/v1/auth/logout551323.64
/api/v2/analytics32721.88
/api/v1/auth/login741621.62
/api/v1/search861315.12
/api/v1/orders1321410.61

Worked solution and explanation

Why this problem exists in real interviews

This is conditional aggregation wearing a reliability costume. The metric is a ratio whose numerator (failed calls) and denominator (all calls) come from the SAME rows, so both have to survive into the aggregate. Anyone can COUNT and divide. The tell the interviewer is watching for: do you filter the error rows in WHERE, or do you keep every row and count the failures with a CASE? Filter them out and the denominator collapses to failures only, so every endpoint reports 100% and the whole ranking is meaningless.


Break down the requirements

Step 1: Keep every call in scope

Do not put status >= 400 in WHERE. The denominator is total traffic, so all calls per endpoint must reach the GROUP BY. The error condition belongs inside the aggregate, not in the row filter.

Step 2: Count failures with a CASE

SUM(CASE WHEN status >= 400 THEN 1 ELSE 0 END) counts 4xx and 5xx responses while COUNT(*) counts everything. Same rows, two different tallies: that is the whole trick.

Step 3: Guard the sample size

HAVING COUNT(*) >= 20 drops thin-traffic endpoints where a single failure would read as a scary rate. HAVING (not WHERE) because the threshold is on the group's row count, computed after grouping.

Step 4: Order worst first

ORDER BY error_rate DESC surfaces the flakiest endpoints on top. The trailing endpoint tie-break just keeps the output stable when two rates match. Multiply the ratio by 100.0 (float) so integer division does not silently floor everything to 0.


The solution

ERROR RATE PER ENDPOINT
SELECT endpoint,
       COUNT(*) AS total_calls,
       SUM(CASE WHEN status >= 400 THEN 1 ELSE 0 END) AS error_calls,
       ROUND(100.0 * SUM(CASE WHEN status >= 400 THEN 1 ELSE 0 END) / COUNT(*), 2) AS error_rate
FROM api_calls
GROUP BY endpoint
HAVING COUNT(*) >= 20
ORDER BY error_rate DESC, endpoint
Naive (wrong)
WHERE status >= 400 ... GROUP BY endpoint. Now COUNT(*) counts only failures, so error_rate is 100% for every endpoint that appears, and clean endpoints vanish entirely. The ranking is destroyed.
Correct
No status filter in WHERE. COUNT(*) is total traffic; SUM(CASE ...) is the failures. The ratio is a true error percentage and endpoints with zero failures still show up at 0.00.

Common follow-up questions