Second Fiddle
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
- Vesta Innovations
Problem
An analyst sizes up each content format in content_items by how many items registered account holders published, so an item whose creator_id has no match in users adds nothing to its format's total. For the format holding the second-highest total (every format, if several tie there), return the full record of each of its items, whoever created it, lowest content_id first.
The spotlight finds number one. The story is in what comes right after.
Tables
content_items
Columns: content_id INTEGER, title TEXT, content_type TEXT, duration_seconds INTEGER, creator_id INTEGER, publish_date TEXT
| content_id | title | content_type | duration_seconds | creator_id | publish_date |
|---|---|---|---|---|---|
| 243 | The Ultimate Guide to AI Trends | article | NULL | 197 | 2026-02-02 |
| 286 | Top 10 Mobile Apps | podcast | 154 | 294 | 2025-03-03 |
| 329 | Understanding Machine Learning [DRAFT] | short | 201 | 391 | 2026-04-04 |
| 372 | Mastering Tech Startups | livestream | 248 | 488 | 2025-05-05 |
| 415 | Introduction to Cybersecurity | video | 295 | 585 | 2026-06-06 |
| 458 | Deep Dive: Cloud Computing | article | NULL | 682 | 2025-07-07 |
| 501 | Behind the Scenes of Product Management | podcast | 389 | 779 | 2026-08-08 |
| 544 | Breaking Down DevOps | short | 436 | 876 | 2025-09-09 |
| 587 | Exploring Web Development | livestream | 483 | NULL | 2026-01-10 |
| 630 | How to Data Science | video | 530 | 1070 | 2025-11-11 |
users
Columns: user_id INTEGER, username TEXT, email TEXT, signup_date TEXT, account_status TEXT, age_bucket TEXT
| user_id | username | signup_date | account_status | age_bucket | |
|---|---|---|---|---|---|
| 100 | alice | alice@example.com | 2025-02-02 | inactive | 25-34 |
| 197 | aaron42 | aaron42@example.com | 2026-03-03 | suspended | 35-44 |
| 294 | amelia | amelia@example.com | 2024-04-04 | pending_verification | 45-54 |
| 391 | arjun | arjun@example.com | 2025-05-05 | active | 55-64 |
| 488 | ava99 | ava99@example.com | 2026-06-06 | inactive | 65+ |
| 585 | andrew_k | andrew_k@example.com | 2024-07-07 | suspended | NULL |
| 682 | anika | anika@example.com | 2025-08-08 16:34:00 | pending_verification | 18-24 |
| 779 | aiden | aiden@example.com | 2026-09-09 14:53:00 | active | 25-34 |
| 876 | aria_b | aria_b@example.com | 2024-10-10 | inactive | 35-44 |
| 973 | brian | brian@example.com | 2025-11-11 | suspended | 45-54 |
Expected output
| content_id | title | content_type | duration_seconds | creator_id | publish_date |
|---|---|---|---|---|---|
| 372 | Mastering Tech Startups | livestream | 248 | 488 | 2025-05-05 |
| 587 | Exploring Web Development | livestream | 483 | NULL | 2026-01-10 |
| 802 | Mastering Tech Startups | livestream | 718 | 1458 | 2025-03-15 |
| 1017 | Exploring Web Development | livestream | 953 | 1943 | 2026-02-20 |
| 1232 | Mastering Tech Startups | livestream | 1188 | 2428 | 2025-01-25 |
Worked solution and explanation
What this really is
Strip the business framing and this is a two-step ranking problem with two separate traps stacked on top of each other. First trap: do you know what DENSE_RANK does that ROW_NUMBER does not when two content types share the exact same count? Second, subtler trap: the registered-creator filter decides WHICH type places second, but it does not decide which rows come back. The question asks for every item of the winning type, whoever published it. Grab 'the second one' with ROW_NUMBER, or re-apply the creator filter on the way out, and the query still runs clean while the answer is quietly wrong.
Break down the requirements
Step 1: Scope to registered creators (for counting only)
Scope content_items to rows whose creator_id appears in users, via WHERE creator_id IN (SELECT user_id FROM users). Content from unregistered creators, and the null creator_id, drops out before any counting happens. This filter exists ONLY to decide the standings, so keep it confined to the counting step.
Step 2: Count per type and rank
GROUP BY content_type with COUNT(*) to get per-type volume, then assign DENSE_RANK() OVER (ORDER BY COUNT(*) DESC). Using DENSE_RANK rather than ROW_NUMBER is what lets tied types share a rank.
Step 3: Keep the second rank
Filter the ranked types to rnk = 2. Because DENSE_RANK gives every tied type the same value, this naturally keeps all types sitting at second place, not just one.
Step 4: Return the full records
Join the qualifying type(s) back to the FULL content_items table, not the filtered set, and sort by content_id, which is unique, so the order is fully determined. Because the creator filter lived only inside the counting step, items from unregistered or null creators reappear here as long as their type placed second. The livestream with a null creator_id (content_id 587) is exactly such a row, and it belongs in the output.
The solution
WITH type_counts AS (
SELECT
content_type,
COUNT(*) AS cnt,
DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS rnk
FROM content_items
WHERE creator_id IN (SELECT user_id FROM users)
GROUP BY content_type
)
SELECT ci.*
FROM content_items ci
INNER JOIN type_counts tc ON ci.content_type = tc.content_type
WHERE tc.rnk = 2
ORDER BY ci.content_idCommon follow-up questions
- How would you change the query if the returned records should ALSO be limited to registered creators? (Tests whether the candidate can articulate the count-versus-return asymmetry as a general modeling idea.)
- How would the answer change if you used `RANK()` instead of `DENSE_RANK()`? (Tests the candidate's grasp of `RANK` vs `DENSE_RANK` gap behavior.)
- How would you compute this if `content_items` were sharded across multiple databases? (Tests distributed query reasoning: where to push down the creator filter and how to merge per-shard type counts.)
- What happens to items whose `creator_id` points at a deleted user, and how does your query treat them? (Tests referential integrity awareness and how the `IN` filter already guards against orphaned creator references during counting.)