Most Efficient Region by Token Usage

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
Meta

Problem

Each row of api_tokens is one access token: its scope, the text dates it was issued and expires, and the requests it has served, where a missing expiration marks a token that never expires and has no lifetime to measure. Per scope, over the tokens that do expire, report the average lifetime in days, the total requests in thousands, and requests per day as average requests over average lifetime, highest requests per day first.

Some regions squeeze more out of every token.

Tables

api_tokens

Columns: token_id INTEGER, owner_id INTEGER, scope TEXT, status TEXT, issued TEXT, expires TEXT, last_used TEXT, requests INTEGER

api_tokens: 10 of 200 rows
token_idowner_idscopestatusissuedexpireslast_usedrequests
1043197writerevoked2025-02-022027-02-022026-02-0247
1086294adminexpired2025-03-032027-03-032026-03-0394
1129391read:usersActive2025-04-042027-04-042026-04-04141
1172488write:ordersREVOKED2025-05-052027-05-052026-05-05188
1215585read:analyticsactive2025-06-062027-06-062026-06-06235
1258682full_accessrevoked2025-07-07NULL2026-07-07282
1301779readexpired2025-08-082027-08-082026-08-08329
1344876writeActive2025-09-092027-09-09NULL0
1387973adminREVOKED2025-10-102027-10-102026-01-10423
14301070read:usersactive2025-11-112027-11-112026-02-11470

Expected output

First 5 of 7 rows
scopeavg_lifetime_daystotal_requests_krequests_per_day
full_access36554.2386.7544209215442095
admin36560.8186.408640674394099
read36551.9825.934018264840182
read:analytics36547.475.911581569115815
write36553.0165.586512118018967

Worked solution and explanation

This is a ratio of two group averages dressed up as token efficiency, with two quieter traps along for the ride. Anyone can write AVG(requests) per scope. What separates candidates is dividing the two averages instead of averaging each token's own requests per day, and remembering that SUM(requests) / 1000 on an integer column throws away everything after the decimal point. Get the ratio wrong and requests per day halves on this data, because half the expiring tokens expire the day they are issued. Get the division wrong and every total comes back as a whole number of thousands.

The decisions that move the numbers

Step 1: Drop the never-expiring tokens first

A NULL in expires means the token never expires, so it has no lifetime. Filter it in WHERE expires IS NOT NULL so it leaves the request total and the request average too. AVG would skip the null lifetime on its own but not the token's requests, and the ratio would then divide averages taken over two different sets of tokens.

Step 2: Turn text dates into days

issued and expires are text. JULIANDAY(expires) - JULIANDAY(issued) turns each pair into a day count. Subtract the strings directly and SQLite reads only the leading year, so a two-year token comes out as 2; Postgres refuses outright.

Step 3: Divide the averages, not each token

Requests per day is AVG(requests) / AVG(lifetime) at the scope level. AVG(requests / lifetime) is a different statistic, and on this seed it meets tokens whose lifetime is 0 days. SQLite turns those divisions into NULL and quietly drops them; Postgres raises an error.

Step 4: Keep the thousands fractional

SUM(requests) over an INTEGER column is an integer, and an integer divided by 1000 is integer division in SQLite and Postgres. CAST(SUM(requests) AS REAL), or dividing by 1000.0, keeps 54.238 from becoming 54.

The solution

Requests per day by scope
SELECT
  scope,
  AVG(JULIANDAY(expires) - JULIANDAY(issued)) AS avg_lifetime_days,
  CAST(SUM(requests) AS REAL) / 1000 AS total_requests_k,
  AVG(requests) / AVG(JULIANDAY(expires) - JULIANDAY(issued)) AS requests_per_day
FROM api_tokens
WHERE expires IS NOT NULL
GROUP BY scope
ORDER BY requests_per_day DESC;

One pass over api_tokens: filter, aggregate per scope, sort by requests_per_day.

Average of each token's ratio
AVG(requests / (JULIANDAY(expires) - JULIANDAY(issued))) weights every token equally and divides by zero on the same-day tokens. On this seed it reports about 3.38 for 'full_access'.
Ratio of the scope's averages
AVG(requests) / AVG(JULIANDAY(expires) - JULIANDAY(issued)) divides volume by lifetime with every token counted once. It reports about 6.75 for 'full_access'.

Common follow-up questions

Common follow-up questions