Creatures of Habit

A hard SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
hard
Seniority
L4
Asked in
Google

Problem

We log every cloud cost allocation by team and service, and we're looking at the teams with real footprints: those with more than 10 allocations on record. Going through those teams in alphabetical order, find each one's most-used fallback service, how many times it landed there, and how many different services the team spreads across in total.

Every big team has one service it can't quit.

Tables

cost_allocs

Columns: alloc_id INTEGER, team_name TEXT, svc_name TEXT, region TEXT, amount REAL, period TEXT, acct_id TEXT, category TEXT

cost_allocs: 10 of 200 rows
alloc_idteam_namesvc_nameregionamountperiodacct_idcategory
129data-engS3us-west-283.212026-02acct-101storage
158ml-teamRDSeu-west-1156.422026-03acct-102network
187frontendLambdaap-south-1229.632026-04acct-103database
216backendBigQueryus-central1-120.52026-05acct-104ml
245devopsCloudFronteurope-west1376.052026-06acct-105other
274securityEKSap-southeast-1449.262026-07acct-106compute
303mobileSQSeu-central-1522.472026-08acct-107storage
332PlatformEC2us-east-1595.682026-09NULLnetwork
361DATA-ENGS3us-west-2668.892026-01acct-109database
390platformRDSeu-west-1742.12026-02acct-110ml

Expected output

First 5 of 10 rows
team_namesvc_namecntsvc_count
DATA-ENGEC238
PlatformCloudFront38
backendBigQuery38
data-engEC238
mobileEKS38

Worked solution and explanation

What this really is

Strip off the cloud-cost costume and this is a per-group argmax reported next to a per-group breadth. For each qualifying team you need the mode of svc_name (the service it lands on most) and, separately, how many DIFFERENT services it touches. The obvious read is a global leaderboard with ORDER BY count then LIMIT 1, which hands back one service for the entire company and silently ignores the per-team requirement. And the two counts pull in opposite directions: 'most often' is a count of rows, while breadth is a count of distinct services, so reusing one for the other quietly inflates the answer.


Stage one: who makes the cut

Step 1: Filter teams by allocation volume

Group by team and keep only teams whose total allocation count clears the bar. The test depends on an aggregate over the whole group, so it belongs after grouping, not before.

Stage two: the habit and the breadth

Step 2: Two counts, kept apart

For the qualifying teams, count rows per (team, service) to get each service's within-team frequency. Separately, count DISTINCT services per team to get breadth. COUNT(*) here answers 'how often'; COUNT(DISTINCT svc_name) answers 'how many different'. A team with twenty allocations spread over eight services has a frequency of twenty rows but a breadth of eight, and swapping one for the other reports breadth as twenty.

Step 3: Pick the top service per team

Number the services inside each team from most-allocated down, then keep the top one. ROW_NUMBER partitioned by team gives exactly one winner per team; a global ORDER BY plus LIMIT would give exactly one winner total. The tie-break on svc_name inside the ORDER BY makes the pick deterministic when several services share the top count.

Global mode (wrong)
Count per service across all qualifying teams, ORDER BY count DESC LIMIT 1. Returns one service for the whole company and drops every team but the accidental winner.
Per-team mode (right)
Count per (team, service), then ROW_NUMBER() OVER (PARTITION BY team ORDER BY count DESC, svc_name). One row per team, each showing that team's own favorite plus its breadth.

The solution

Volume filter, per-team mode, and a separate distinct breadth
WITH big_teams AS (
  SELECT team_name
  FROM cost_allocs
  GROUP BY team_name
  HAVING COUNT(*) > 10
),
svc_counts AS (
  SELECT team_name, svc_name, COUNT(*) AS cnt
  FROM cost_allocs
  WHERE team_name IN (SELECT team_name FROM big_teams)
  GROUP BY team_name, svc_name
),
breadth AS (
  SELECT team_name, COUNT(DISTINCT svc_name) AS svc_count
  FROM cost_allocs
  GROUP BY team_name
),
ranked AS (
  SELECT team_name, svc_name, cnt,
         ROW_NUMBER() OVER (PARTITION BY team_name ORDER BY cnt DESC, svc_name) AS rn
  FROM svc_counts
)
SELECT r.team_name, r.svc_name, r.cnt, b.svc_count
FROM ranked r
JOIN breadth b ON r.team_name = b.team_name
WHERE r.rn = 1
ORDER BY r.team_name

The tie-break on svc_name inside ORDER BY makes the winner deterministic; COUNT(DISTINCT svc_name) is what keeps breadth honest.


Common follow-up questions