The Warm Edges

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
Postmates by Uber

Problem

The CDN team is comparing API traffic at the edge locations that are actually caching: those that have logged at least one cache hit on any path. For request paths that include 'api', find the average bytes served at each edge location and path combination, leanest first.

Some edges keep the cache warm. Measure what they carry.

Tables

cdn_logs

Columns: log_id INTEGER, edge_loc TEXT, req_path TEXT, status INTEGER, bytes INTEGER, cache_hit INTEGER, served_at TEXT

cdn_logs: 10 of 200 rows
log_idedge_locreq_pathstatusbytescache_hitserved_at
537SFO/js/app.min.js200143702026-02-02 01:07:13
574LHR/css/main.css200277402026-03-03 02:14:26
611NRT/images/hero.jpg206411112026-04-04 03:21:39
648SIN/api/v1/data301544802026-05-05 04:28:52
685FRA/fonts/roboto.woff2304NULL02026-06-06 05:35:05
722SYD/video/intro.mp44038122NULL2026-07-07 06:42:18
759GRU/favicon.ico4049459NULL2026-08-08 07:49:31
796IAD/assets/logo.png?v=250010796NULL2026-09-09 08:56:44
833SFO/js/app.min.js 50312133NULL2026-01-10 09:03:57
870LHR/assets/logo.png2001347002026-02-11 10:10:10

Expected output

First 4 of 4 rows
edge_locreq_pathavg_bytes
IAD/api/v1/data58928
SIN/api/v1/data58928
LHR/api/v1/data72298
SYD/api/v1/data72298

Worked solution and explanation

What this really tests

Strip the CDN costume and this is a set-membership filter feeding an aggregate: average bytes per (edge, path), but only over edges that belong to a separately-computed set (those that ever cached). The trap is where you put cache_hit = 1. Put it in the outer WHERE and you silently average only cache-hit rows, which is a different number. Keep it inside the qualifying subquery and you average all API traffic at edges that happen to cache. On 2B rows the interviewer also watches which membership shape you reach for: a JOIN (SELECT DISTINCT ...), an IN subquery, or EXISTS. All three are correct; they scan and materialize differently.


Break down the requirements

Step 1: Build the qualifying edge set

SELECT DISTINCT edge_loc FROM cdn_logs WHERE cache_hit = 1. This is a separate logical pass over cdn_logs. Distinct edge count is small (hundreds), so the result is tiny even though the scan is large.

Step 2: Filter main scan to API paths

WHERE cl.req_path LIKE '%api%'. Leading wildcard kills index use; you are scanning anyway because of the aggregation, so this is fine. State that out loud so the interviewer knows you noticed.

Step 3: Inner join, not IN, not EXISTS

JOIN (subquery) ON edge_loc = edge_loc. The qualifying set is small enough to broadcast or hash-build cheaply. IN (SELECT ...) and EXISTS work but force the planner to re-evaluate per row on some engines.

Step 4: Aggregate and sort low to high

GROUP BY cl.edge_loc, cl.req_path, AVG(cl.bytes), then ORDER BY avg_bytes, cl.edge_loc, cl.req_path (ascending, the prompt says leanest first). Two (edge, path) combinations can share an average, so the edge_loc then req_path tiebreakers make the order total: without them the tied rows come back in engine order and a correct answer can grade wrong. Each group has a unique (edge_loc, req_path), so those two keys fully determine the row order. No LIMIT requested.


The solution

THE WARM EDGES
SELECT
  cl.edge_loc,
  cl.req_path,
  AVG(cl.bytes) AS avg_bytes
FROM cdn_logs cl
JOIN (
  SELECT DISTINCT edge_loc
  FROM cdn_logs
  WHERE cache_hit = 1
) cached
  ON cl.edge_loc = cached.edge_loc
WHERE cl.req_path LIKE '%api%'
GROUP BY cl.edge_loc, cl.req_path
ORDER BY avg_bytes, cl.edge_loc;

COMMON FOLLOW-UP QUESTIONS

Common follow-up questions