# Top of the Line

> The five priciest items for the luxury section.

Canonical URL: <https://datadriven.io/problems/top_of_the_line>

Domain: SQL · Difficulty: easy · Seniority: L3

## Problem

The editorial team is assembling a buyer's guide and needs the five most expensive products for the luxury highlight section. Show the product name, category, price, and whether the item is currently available. Products without a listed price should be excluded.

## Worked solution and explanation

### What this is really testing

Do not let the buyer's-guide framing fool you: this is the simplest query on the ladder, a filter, a sort, and a cut. The whole test is whether you resist the urge to reach for GROUP BY or a window function when a plain sort with a limit already does the job. Two quiet things separate a clean answer from a sloppy one: the null prices that will misbehave if you leave them in, and the tie at the fifth slot that makes the result change from run to run unless you add a second sort key. Miss either and the query still runs, which is exactly why it is dangerous: it returns a plausible wrong answer.

---

### The three things that actually matter

#### Step 1: Drop the unpriced rows first

About 8 percent of products have no price. In SQLite a NULL is treated as smaller than any number, so under a descending sort it drops to the bottom and will not climb into the top five on its own. But an unpriced item is not a candidate for 'most expensive' by definition, so WHERE price IS NOT NULL makes that intent explicit rather than relying on how the engine happens to order nulls.

#### Step 2: Sort by price, then break the tie

ORDER BY price DESC puts the most expensive first. If two products share the price sitting at position five, the database is free to return either one, and the result flips between runs. A second key, product_name ASC, settles equal prices alphabetically and makes the output deterministic. This is the detail an interviewer is quietly watching for.

#### Step 3: Take exactly five

LIMIT 5 truncates after the sort. Order of operations matters: the engine sorts the whole filtered table first, then keeps the first five rows. It is not limiting and then sorting, which would give you an arbitrary five in sorted order.

### The solution

**Filter out unpriced rows, sort by price descending, break ties by name, take five**

```sql
SELECT product_name, category, price, in_stock
FROM products
WHERE price IS NOT NULL
ORDER BY price DESC, product_name ASC
LIMIT 5
```

> **Common Pitfall**
>
> The buyer's-guide story makes people reach for machinery they do not need: GROUP BY product_id, a ROW_NUMBER window, a subquery of maxes. There is already one row per product, so there is nothing to aggregate. Every extra clause is a new place to introduce a bug on a problem that is four lines long.

> **Interviewers Watch For**
>
> On a screen this easy the signal is in the two edges. A candidate who adds the null filter and a tie-break on product_name without being told is showing they think about missing data and determinism by habit. That instinct is what the question is really buying.

> **Performance Insight**
>
> On 6,000 rows this is trivial, but the pattern scales. With an index on price the engine can walk it in descending order and stop after five rows, never sorting the full table. That top-N-from-an-index plan is why ORDER BY with LIMIT beats pulling every row into the application and slicing there.

---

## Common follow-up questions

- If two products tie on price at the fifth slot, does LIMIT 5 pick one arbitrarily, and how would you return both? _(Tests awareness that LIMIT truncates arbitrarily; some engines offer FETCH FIRST 5 ROWS WITH TIES to keep both.)_
- If the table has fewer than five priced products, what does LIMIT 5 return? _(Tests understanding that LIMIT returns up to N rows, not exactly N.)_
- How would this change if you needed the top five per category instead of the top five overall? _(Tests the jump to a window function (ROW_NUMBER partitioned by category) once per-group ranking is genuinely required, which is exactly what this problem did NOT need.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/top_of_the_line)
- [SQL Interview Questions](https://datadriven.io/sql-interview-questions)
- [Data Engineering Interview Prep Guide](https://datadriven.io/data-engineer-interview-prep)
- [Daily Challenge](https://datadriven.io/daily)

---

Source: DataDriven (https://datadriven.io). DataDriven is the data engineering interview community. Live code execution in SQL, Python, and Spark sandboxes. Every feature is open to every member.