Cost Share Within Category

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
Google

Problem

List every compute, storage and network allocation in cost_allocs with its allocation ID, category, amount, and the percent of its category's total spend it accounts for, counting a whole category as 100, sorted by category and then by allocation ID. The FinOps analyst reading it wants amounts in whole dollars with the cents dropped, though the percentages still come from the exact amounts.

Each entry's slice of the category total.

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 101 rows
alloc_idcategorywhole_dollar_amountpct_of_category
274compute4490.15938693468477672
448compute8880.31522610338360374
158network1560.05442914089297334
332network5950.2072775261931106
129storage830.029234427256955933

Worked solution and explanation

What this is really testing

This is a share-of-total dressed up as a FinOps review. The question is whether you can put each category's total beside every one of its allocations without collapsing them. Anyone can total spend per category. The trap is doing it with GROUP BY category: the totals come out right, but the 101 allocation rows fold into three, alloc_id can no longer be selected, and no row is left to hold a per-allocation percentage. A window SUM(amount) OVER (PARTITION BY category) attaches the total in one pass and keeps every row.


Break down the requirements

Step 1: Filter to the three categories

WHERE category IN ('compute', 'storage', 'network') drops 'database', 'ml' and 'other', including the -120.50 credit sitting in 'ml'. The window is evaluated after WHERE, so it only sees the rows you keep.

Step 2: Put the category total on every row

SUM(amount) OVER (PARTITION BY category) gives each row the total of its own category. There is no ORDER BY inside the window, so the frame is the whole partition. The rows stay and the denominator rides along with them.

Step 3: Turn the share into a percentage

100 * amount / SUM(amount) OVER (...) computes the percentage from the exact amounts. amount is REAL, so the division is floating point and nothing gets truncated to zero.

Step 4: Drop the cents only for display

CAST(amount AS INTEGER) turns 449.26 into 449 for whole_dollar_amount. It touches only the displayed column; the percentage keeps reading the exact amount. Then sort by category and alloc_id.

Window sum for within-category share
SELECT
    alloc_id,
    category,
    CAST(amount AS INTEGER) AS whole_dollar_amount,
    100 * amount / SUM(amount) OVER (PARTITION BY category) AS pct_of_category
FROM cost_allocs
WHERE category IN ('compute', 'storage', 'network')
ORDER BY category, alloc_id
Per-category total
GROUP BY category with SUM(amount) returns three rows. alloc_id and each allocation's amount are gone, so there is nothing left to divide.
Total beside each row
SUM(amount) OVER (PARTITION BY category) returns all 101 allocations, each carrying its category's total, so 100 * amount / total works on every row.

Common follow-up questions