# Three Lowest Distinct Cloud Cost Amounts

> The three cheapest bills on record.

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

Domain: SQL · Difficulty: easy · Seniority: L3

## Problem

Surface the three lowest unique cloud cost amounts. If two line items share the same amount, count that as one value.

## Worked solution and explanation

### What this is really asking

`cloud_costs.amount` repeats heavily across 6M rows. The prompt wants three distinct values, not three rows. Skip `DISTINCT` and you return three identical line items that all happen to share the cheapest amount.

---

### Break down the requirements

#### Step 1: Project just the amount

Select only `amount` from `cloud_costs`. Other columns would force per-row distinctness, not per-amount distinctness.

#### Step 2: Dedupe with DISTINCT

`SELECT DISTINCT amount` collapses repeated values to one row each.

#### Step 3: Sort ascending, take 3

`ORDER BY amount ASC LIMIT 3`. Ascending is non-negotiable; the prompt says lowest.

---

### The solution

**DISTINCT THEN SORT THEN LIMIT**

```sql
SELECT DISTINCT amount
FROM cloud_costs
ORDER BY amount ASC
LIMIT 3
```

> **Cost Analysis**
>
> 6M rows, partitioned by `bill_date` which the query never filters on. Full scan plus a hash-distinct on `amount`. An index on `amount` would let the planner stream the lowest values without sorting the whole table.

> **Interviewers Watch For**
>
> Whether you read `unique` as `DISTINCT amount`, not `DISTINCT *`. Also whether you notice the prompt scope: cloud-wide, not per-provider or per-region. A senior would confirm that before writing.

> **Common Pitfall**
>
> `SELECT amount FROM cloud_costs ORDER BY amount ASC LIMIT 3` without DISTINCT returns the three cheapest line items, which are often the same dollar amount. Three rows, one unique value, wrong answer.

> **The False Start**
>
> First instinct is `GROUP BY amount` plus a `HAVING` filter, treating duplicates as a count problem. That works but adds an aggregate the prompt does not ask for. Pivot to `DISTINCT`: it expresses unique-values cleanly without inviting follow-up questions about counts.

---

### COMMON FOLLOW-UP QUESTIONS

## Common follow-up questions

- How would you return the three cheapest amounts per provider? _(Tests window functions: `DENSE_RANK() OVER (PARTITION BY provider ORDER BY amount)` filtered to rank <= 3.)_
- What if the prompt asked for the three cheapest amounts and the services that hit them? _(Now you need the row, not just the value. Use a CTE with the three lowest distinct amounts, then join back to `cloud_costs` and accept the fanout.)_
- How does the answer change if `amount` can be NULL? _(`DISTINCT` keeps a NULL bucket; `ORDER BY ASC` places NULLs first in SQLite and last in Postgres. Either filter NULLs out or be explicit about the engine.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/three_lowest_distinct_cloud_cost_amounts)
- [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). 100% free data engineering interview prep. Live code execution against Postgres 16, Python 3.11, and Spark sandboxes. No paywall, no premium tier, no signup gate.