Content Sorted by Duration
An easy SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.
- Domain
- SQL
- Difficulty
- easy
- Seniority
- L3
- Asked in
- Allstate
Problem
Nobody can tell from our content report how far each piece in content_items runs short of the longest one in the whole catalog. Return every item with all of its columns, its duration, and that shortfall, both figures in seconds as decimals.
The catalog, sorted by length.
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 |
Expected output
| content_id | title | content_type | duration_seconds | creator_id | publish_date | duration_decimal | diff_from_longest |
|---|---|---|---|---|---|---|---|
| 243 | The Ultimate Guide to AI Trends | article | NULL | 197 | 2026-02-02 | NULL | NULL |
| 286 | Top 10 Mobile Apps | podcast | 154 | 294 | 2025-03-03 | 154 | 4606 |
| 329 | Understanding Machine Learning [DRAFT] | short | 201 | 391 | 2026-04-04 | 201 | 4559 |
| 372 | Mastering Tech Startups | livestream | 248 | 488 | 2025-05-05 | 248 | 4512 |
| 415 | Introduction to Cybersecurity | video | 295 | 585 | 2026-06-06 | 295 | 4465 |
Worked solution and explanation
One number, every row
This is a broadcast of one table-wide scalar dressed up as a content report. Anyone can find the longest duration. The trap is computing it in the same pass as the detail rows: SELECT *, MAX(duration_seconds) - duration_seconds mixes a bare aggregate with row-level columns, and SQLite does not error. It quietly collapses the whole catalog to one arbitrary row. The team asked for every item and gets one. The fix is to compute the maximum on its own, hand that single value to every row, then cast both figures so they come back as decimals.
Step 1: Compute the longest duration once
(SELECT MAX(duration_seconds) FROM content_items) is a scalar subquery: one row, one column, usable like a constant inside the outer SELECT. MAX skips the NULL durations, so the value is the true catalog-wide longest.
Step 2: Keep every row and every column
SELECT * over content_items with no WHERE and no grouping keeps all 200 items, including the 40 with no duration. Nothing is aggregated in the outer query, so nothing collapses.
Step 3: Cast both figures to decimals
CAST(duration_seconds AS REAL) gives duration_decimal. The gap is an integer minus an integer, which stays an integer, so the whole difference gets its own cast to become diff_from_longest. An item with a NULL duration gets NULL in both.
SELECT
*,
CAST(duration_seconds AS REAL) AS duration_decimal,
CAST((SELECT MAX(duration_seconds) FROM content_items) - duration_seconds AS REAL) AS diff_from_longest
FROM content_itemsThe longest item gets a diff_from_longest of 0.0.
-- One row comes back, not the catalog
SELECT *, MAX(duration_seconds) - duration_seconds AS diff_from_longest
FROM content_itemsA bare aggregate without GROUP BY reduces the whole table to a single row.
- Scalar subquery
(SELECT MAX(duration_seconds) FROM content_items)is evaluated once, and the outer scan reads it as a constant.- Window over the whole table
MAX(duration_seconds) OVER ()puts the same value on every row, but a window with no partition key must see the entire table first, so a distributed engine funnels every row through one worker.
Common follow-up questions
- How does `MAX(duration_seconds) OVER ()` differ from the scalar subquery? (Same values on every row. Tests whether you know a window with no partition key has nothing to spread its work across.)
- How would you also show each item's position by duration, longest first? (A window ordered by `duration_seconds` descending. Watch where the `NULL` durations land.)
- What if the team wanted the gap from the average duration instead? (Swap `MAX` for `AVG` in the subquery. Items above the average then get a negative gap.)