First Contact

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
L3
Asked in
Uber

Problem

We're measuring first-impression latency from api_calls: for the first call each user makes to a given endpoint, how long it took in whole milliseconds with the timer's fractional digits dropped, where calls with no user attached all count as one anonymous visitor. The log sometimes records an endpoint with stray spaces or a trailing slash, and those spellings are the same endpoint. Report the average first-contact latency for every endpoint, slowest first.

Every user's first hello to an endpoint. Timed.

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 8 rows
endpointavg_initial_call_latency
/api/v1/auth/logout402.76190476190476
/api/v1/search383.1014492753623
/api/v1/auth/login354.6271186440678
/api/v1/payments276.6
/api/v2/products272.18

Worked solution and explanation

What this is really asking

This is a per-group first-occurrence pick wearing a latency-report costume. For every (user, route) pair you want exactly one row, the earliest call, and only then do you average within each route. The trap is AVG(latency) GROUP BY endpoint straight off the raw table. That answers 'average latency per endpoint', a different number dominated by whoever calls the most. Miss the dedup and your first-impression metric quietly becomes a traffic-weighted average of everyone's repeat traffic.


Break down the requirements

Step 1: Fold the endpoint spellings into one route

The log writes one route several ways: '/api/v1/orders ' with a trailing space, '/api/v1/users/' with a trailing slash. RTRIM(TRIM(endpoint), '/') strips the padding and then the slash. Clean the key first, because everything downstream partitions and groups on it.

Step 2: Number each user's calls to each route by time

ROW_NUMBER() OVER (PARTITION BY user_id, RTRIM(TRIM(endpoint), '/') ORDER BY call_time). Partitioning by user and cleaned route gives one earliest row per pair, so a chatty user contributes a single first contact per route. NULL user_id rows share one partition, which is exactly the one anonymous visitor the statement describes.

Step 3: Keep only each user's first call per route

Filter on rn = 1 in an outer query. A window function cannot live in WHERE, so the derived table is mandatory, not stylistic. This is the row set of genuine first impressions.

Step 4: Floor each latency, average per route, and order

AVG(CAST(latency AS INTEGER)) floors every surviving latency to a whole millisecond before averaging. Grouping by the cleaned endpoint gives one number per route, and sorting that average descending puts the slowest first impressions on top.


The solution

FIRST CONTACT
SELECT endpoint,
       AVG(CAST(latency AS INTEGER)) AS avg_initial_call_latency
FROM (
  SELECT RTRIM(TRIM(endpoint), '/') AS endpoint,
         latency,
         ROW_NUMBER() OVER (
           PARTITION BY user_id, RTRIM(TRIM(endpoint), '/')
           ORDER BY call_time
         ) AS rn
  FROM api_calls
) first_calls
WHERE rn = 1
GROUP BY endpoint
ORDER BY avg_initial_call_latency DESC

COMMON FOLLOW-UP QUESTIONS

Common follow-up questions