Top API Caller

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
Walmart

Problem

Our API load runs higher than our known accounts can explain, and calls logged without a user are a suspect too. From api_calls, find the single biggest caller with its total number of calls.

One user triggered more API calls than anyone.

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 1 of 1 rows
user_idcall_count
NULL17

Worked solution and explanation

What this is really asking

This is a find-the-mode question in an API costume: count every row of api_calls per user_id and keep the top bucket. Anyone writes the grouping. What separates candidates is what they do with the 17 calls that carry no user_id. The reflex is to scrub them out with WHERE user_id IS NOT NULL as dirty data. But the grouping already gathers them into one bucket, and that bucket is the biggest caller in the log. Filter it away and you report a known user with 13 calls: the wrong caller and the wrong count.

Step 1: Count every row per user_id

COUNT(*) counts rows, so failed calls, redirects and calls with no user all add to the total. GROUP BY user_id puts every NULL into a single group, which is the unattributed traffic the statement names as a suspect.

Step 2: Keep the single top bucket

Sort the counts with call_count DESC and cut with LIMIT 1. The top of this log is not tied (17 against 13), so no tiebreaker can change which row survives.

The solution

Top API caller
SELECT
  user_id,
  COUNT(*) AS call_count
FROM api_calls
GROUP BY user_id
ORDER BY call_count DESC
LIMIT 1;
The scrubbed version
SELECT
  user_id,
  COUNT(*) AS call_count
FROM api_calls
WHERE user_id IS NOT NULL
GROUP BY user_id
ORDER BY call_count DESC
LIMIT 1;

Dropping NULL user_id rows first returns a 13-call user instead of the 17-call bucket.

Scrubbed first
WHERE user_id IS NOT NULL deletes 17 real calls before counting, and the winner becomes a known user with 13.
Grouped as logged
GROUP BY user_id keeps the NULLs together as one caller, and that caller wins with 17.

Follow-up questions

Common follow-up questions