Feature Vote Winner
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
- EY
Problem
An entry in feat_flags with no rollout figure is an abstention, and each team (owner) splits exactly one vote evenly across the entries it did fill in. The product council's planning review needs every flag's effective vote total as a decimal, alongside that total as a percentage of the leading flag's.
Users voted with their clicks. Who won?
Tables
feat_flags
Columns: flag_id INTEGER, flag_name TEXT, enabled INTEGER, rollout REAL, owner TEXT, created TEXT, updated TEXT
| flag_id | flag_name | enabled | rollout | owner | created | updated |
|---|---|---|---|---|---|---|
| 131 | new_checkout | 0 | NULL | engineering | 2025-02-02 | 2026-02-02 |
| 162 | beta_search | 0 | NULL | growth | 2025-03-03 | 2026-03-03 |
| 193 | ai_recs | 1 | 39 | platform | 2025-04-04 | 2026-04-04 |
| 224 | live_chat | 0 | NULL | mobile | 2025-05-05 | 2026-05-05 |
| 255 | video_upload | 0 | NULL | data | 2025-06-06 | 2026-06-06 |
| 286 | two_factor | 1 | 78 | product | 2025-07-07 | 2026-07-07 |
| 317 | bulk_export | 0 | NULL | engineering | 2025-08-08 | 2026-08-08 |
| 348 | new_dashboard | 0 | NULL | growth | 2025-09-09 | 2026-09-09 |
| 379 | mobile_v2 | 1 | 17 | platform | 2025-10-10 | 2026-01-10 |
| 410 | dark_mode | 0 | NULL | mobile | 2025-11-11 | 2026-02-11 |
Expected output
| flag_name | effective_votes | pct_of_leader |
|---|---|---|
| ai_recs | 0.23529411764705882 | 94.11764705882352 |
| beta_search | 0.1875 | 75 |
| bulk_export | 0.1764705882352941 | 70.58823529411764 |
| mobile_v2 | 0.23529411764705882 | 94.11764705882352 |
| two_factor | 0.25 | 100 |
Worked solution and explanation
What this really is
This is a reciprocal-weighted tally dressed up as a feature vote. There is no ballots table: feat_flags is the ballot, owner is the voter, and a filled-in rollout is the mark on the paper. Anyone can sum per flag. The trick is that the denominator and the tally must read the same filtered set. On this data only 'product' and 'platform' filled in any rollout. Skip the filter and 'engineering', 'growth', 'mobile' and 'data' each spread a whole vote over entries they never backed, so the totals sum to 6 instead of 2 and the percentages drift.
The second trap is arithmetic. 1 / backed_flags with two integers floors to 0 for any team with two or more backings, which is every team here. Every total collapses to zero and the percentage divides by zero.
Building it
Step 1: Isolate the backings once
Put WHERE rollout IS NOT NULL in a backings CTE and read only from it afterwards. Filtering in one place is what guarantees the ballot size and the tally agree on which entries count.
Step 2: Count each team's ballot
COUNT(*) grouped by owner over backings gives backed_flags, the number a team's single vote gets divided by.
Step 3: Join the denominator back and sum reciprocals
Join backings to ballot_sizes on owner, then SUM(CAST(1 AS REAL) / bs.backed_flags) per flag_name. The cast makes the division fractional; each team now contributes exactly 1.0 across all its entries.
Step 4: Measure everyone against the leader
The leader's total is an aggregate over flag_totals, not over raw rows, so a scalar subquery (SELECT MAX(effective_votes) FROM flag_totals) supplies it to every row. Multiply by 100.0 so the leader reads 100.
WITH backings AS (
SELECT flag_name, owner
FROM feat_flags
WHERE rollout IS NOT NULL
),
ballot_sizes AS (
SELECT owner, COUNT(*) AS backed_flags
FROM backings
GROUP BY owner
),
flag_totals AS (
SELECT b.flag_name,
SUM(CAST(1 AS REAL) / bs.backed_flags) AS effective_votes
FROM backings b
JOIN ballot_sizes bs ON b.owner = bs.owner
GROUP BY b.flag_name
)
SELECT flag_name,
effective_votes,
effective_votes * 100.0 / (SELECT MAX(effective_votes) FROM flag_totals) AS pct_of_leader
FROM flag_totals- No abstention filter
ballot_sizesand the tally read all offeat_flags: the four teams that filled in norollouteach hand out a full vote across their entries, and the flag totals sum to 6.- Filter at the source
- Both read
backings: only 'product' and 'platform' vote, each team's weights sum to exactly 1.0, and the flag totals sum to 2, the number of voting teams.
Common follow-up questions
- Return only the flags within 10 points of the leader. (Moves `pct_of_leader` into a filter and checks the candidate keeps the leader computed over `flag_totals`.)
- What if a team listed the same flag twice? (Probes whether the candidate notices the tally counts entries, not unique flags, and how a dedup on `owner` and `flag_name` changes the weights.)
- Rewrite the leader comparison without a subquery. (Tests `MAX(effective_votes) OVER ()` as a window over the per-flag totals.)
- feat_flags (source, table)
- backings (transform, rollout filled)
- ballot_sizes (transform, count per team)
- flag_totals (transform, sum of reciprocals)
- report (consumer, share of leader)
- feat_flags -> backings
- backings -> ballot_sizes
- backings -> flag_totals
- ballot_sizes -> flag_totals
- flag_totals -> report