Three Peaks
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
- Maanams International
Problem
cost_allocs records cloud spend as individual allocations, each tagged to a team and a billing period, so a team's monthly cost is everything allocated to it in that period. Team names were entered with inconsistent capitalization, and every capitalization of a name is the same team. Surface the three highest unique monthly cost amounts for each team.
Every team's steepest months, and nothing below them.
Tables
cost_allocs
Columns: alloc_id INTEGER, team_name TEXT, svc_name TEXT, region TEXT, amount REAL, period TEXT, acct_id TEXT, category TEXT
| alloc_id | team_name | svc_name | region | amount | period | acct_id | category |
|---|---|---|---|---|---|---|---|
| 129 | data-eng | S3 | us-west-2 | 83.21 | 2026-02 | acct-101 | storage |
| 158 | ml-team | RDS | eu-west-1 | 156.42 | 2026-03 | acct-102 | network |
| 187 | frontend | Lambda | ap-south-1 | 229.63 | 2026-04 | acct-103 | database |
| 216 | backend | BigQuery | us-central1 | -120.5 | 2026-05 | acct-104 | ml |
| 245 | devops | CloudFront | europe-west1 | 376.05 | 2026-06 | acct-105 | other |
| 274 | security | EKS | ap-southeast-1 | 449.26 | 2026-07 | acct-106 | compute |
| 303 | mobile | SQS | eu-central-1 | 522.47 | 2026-08 | acct-107 | storage |
| 332 | Platform | EC2 | us-east-1 | 595.68 | 2026-09 | NULL | network |
| 361 | DATA-ENG | S3 | us-west-2 | 668.89 | 2026-01 | acct-109 | database |
| 390 | platform | RDS | eu-west-1 | 742.1 | 2026-02 | acct-110 | ml |
Expected output
| team_name | monthly_cost |
|---|---|
| backend | 20834.33 |
| backend | 16691.79 |
| backend | 15780.49 |
| data-eng | 34333.24 |
| data-eng | 31743.24 |
Worked solution and explanation
What this really is
Under the finance wording, this is a per-team top-N on a figure you have to build first. A team's monthly cost is everything allocated to it in that period, across every service, region, account and category. That is SUM(amount) grouped by team and period, never one row's amount. Anyone can write the sum. The trap is the scope of the ranking. Write ORDER BY monthly_cost DESC LIMIT 3 and you get the three biggest figures in the whole company. That is three rows in total, so most teams vanish from the report. Two smaller catches follow. The answer is amounts, not months, so two months with the same total share one slot. And the same team shows up under more than one capitalization, so its spend has to be pooled under one name before anything is summed.
Building it
Step 1: Pool each team's month under one name
cost_allocs holds many rows per team and month, one per service, region, account and category. All of them count toward that month. Group on LOWER(team_name), not the raw value: 'data-eng' and 'DATA-ENG' are one team, and so are 'Platform' and 'platform'. Use the same expression in the SELECT so the output carries one spelling.
Step 2: Drop period, then deduplicate
SELECT DISTINCT team_name, monthly_cost makes three slots mean three different amounts. It only works once period is gone. Leave period in and every row stays distinct, so nothing collapses.
Step 3: Rank inside each team, filter outside
DENSE_RANK() restarts at 1 for every team_name. Filter rnk <= 3 in the outer query, because WHERE cannot see a window alias defined in its own SELECT. The ORDER BY inside OVER (...) only assigns ranks; the report itself is a set of rows, so no outer sort is needed.
The solution
WITH monthly AS (
SELECT LOWER(team_name) AS team_name, period, SUM(amount) AS monthly_cost
FROM cost_allocs
GROUP BY LOWER(team_name), period
),
distinct_costs AS (
SELECT DISTINCT team_name, monthly_cost
FROM monthly
),
ranked AS (
SELECT
team_name,
monthly_cost,
DENSE_RANK() OVER (
PARTITION BY team_name
ORDER BY monthly_cost DESC
) AS rnk
FROM distinct_costs
)
SELECT team_name, monthly_cost
FROM ranked
WHERE rnk <= 3
;One CTE per intermediate result: totals in monthly, unique amounts in distinct_costs, ranks in ranked.
- Global limit
ORDER BY monthly_cost DESC LIMIT 3overmonthlyreturns three rows for the whole company, all from whichever teams spend most.- Partitioned window
PARTITION BY team_namerestarts the rank per team, sornk <= 3keeps up to three distinct amounts for every team.
WITH monthly AS (
SELECT LOWER(team_name) AS team_name, period, SUM(amount) AS monthly_cost
FROM cost_allocs
GROUP BY LOWER(team_name), period
)
SELECT team_name, monthly_cost
FROM monthly
ORDER BY monthly_cost DESC
LIMIT 3;Three rows in total instead of three per team, and equal totals never collapse.
Common follow-up questions
- How would you return the month or months each top amount came from? (Tests joining `ranked` back to `monthly` on `team_name` and `monthly_cost`, which can yield several rows per amount.)
- What if a team has fewer than three months of data? (Tests seeing that `rnk <= 3` simply returns the amounts that team has.)
- Could you drop the `distinct_costs` CTE and still get unique amounts? (Tests `DENSE_RANK()` over `monthly` followed by `SELECT DISTINCT` on the survivors.)
- What if some team names also arrived with stray spaces? (Tests adding `TRIM` alongside `LOWER` and fixing the data at write time instead.)