Successful Call Volume per Endpoint

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
L5
Asked in
PayPal

Problem

Most of the gateway traffic logged in api_calls piles onto a few heavy routes, and the reliability team wants to know how much of that load actually succeeds. Count the successful calls, those with status 200, for every endpoint handling at least half the call volume of the single busiest route, most successes first.

Not every ping is honest.

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 5 rows
endpointsuccessful_calls
/api/v1/users116
/api/v1/orders113
/api/v2/products107
/api/v1/search66
/api/v1/auth/login51

Worked solution and explanation

What this really is

Strip the costume and this is a group filter whose bar comes from the groups themselves. Roll up each endpoint's total traffic, take the busiest route's total, keep only routes carrying at least half of it, and only then count the status-200 calls for the survivors. Anyone can write the final count. The separation is which volume sets the bar: gate on successes instead of total calls and '/api/v1/auth/login' disappears, because its 51 successes sit under half of the top route's 116 while its total traffic easily clears the real bar. That is the route with the 401 storms, the one a reliability team most needs on the page.

The two-stage shape

Step 1: Roll up total volume per endpoint

Each endpoint's TOTAL calls, failures included, is what defines busy. One pass over api_calls grouped by endpoint gives one row per route. Stage it as endpoint_totals so it is computed once and read twice: for the benchmark and for the membership test.

Step 2: Benchmark against the busiest route

The busiest route's total is MAX(total_calls) over endpoint_totals, a single value. Keep the endpoints where total_calls * 2 >= that value. Taking the max over the rollup, not over raw rows, is what makes the bar a route-level figure; doubling the left side keeps the comparison in integers.

Step 3: Count only the successes for the survivors

Scan api_calls again, keep status = 200, restrict to endpoints that passed the gate, and count per endpoint. Sort by successful_calls descending; the grader checks the rows are in that order and nothing else.

Naive: gate on the wrong volume
Filter endpoints by their count of status = 200 rows, or compare against a row-grain figure. The error-heavy login route falls out, or nothing is filtered at all.
Correct: rollup, then gate
Build endpoint_totals, take MAX(total_calls), keep endpoints at or above half of it, then count only the status = 200 rows for that set.
Successful call volume for the heavy-traffic endpoints
WITH endpoint_totals AS (
    SELECT endpoint, COUNT(*) AS total_calls
    FROM api_calls
    GROUP BY endpoint
)
SELECT endpoint, COUNT(*) AS successful_calls
FROM api_calls
WHERE status = 200
  AND endpoint IN (
      SELECT endpoint
      FROM endpoint_totals
      WHERE total_calls * 2 >= (SELECT MAX(total_calls) FROM endpoint_totals)
  )
GROUP BY endpoint
ORDER BY successful_calls DESC

One CTE feeds both the MAX benchmark and the membership test; the final count keeps only status = 200.

Common follow-up questions