SELECT DISTINCT bouquets.name, bouquets.price
FROM bouquets
JOIN flowers ON bouquets.id = flowers.bouquet_id
JOIN flower_varieties ON flowers.variety_id = flower_varieties.id
WHERE flower_varieties.variety = 'Carnation'
ORDER BY bouquets.name
LIMIT 1;
We need to find the first bouquet (alphabetically) that contains at least one Carnation flower. This is similar to a real-world scenario where a customer asks: "What's your least expensive bouquet that includes roses?" The challenge is that we need to:
Our query connects three tables in a chain:
bouquets → flowers → flower_varieties
(names, (links (master list
prices) them) of varieties)
Think of this like finding a recipe that uses a specific ingredient:
SELECT DISTINCT bouquets.name, bouquets.price
The DISTINCT keyword is crucial here because:
JOIN flowers ON bouquets.id = flowers.bouquet_id
This JOIN connects each bouquet to its flowers. It's like opening each recipe and seeing its ingredients. We use INNER JOIN because:
JOIN flower_varieties ON flowers.variety_id = flower_varieties.id
This JOIN identifies what type each flower is. It's like looking up each ingredient in a master list to confirm it's a Carnation.
WHERE flower_varieties.variety = 'Carnation'
This filters for only Carnations. Note that:
ORDER BY bouquets.name LIMIT 1;
These ensure we get exactly what we want:
1. Start with bouquets:
id | name | price
1 | Get Well Soon | 59.99
2 | Mother's Day | 39.99
2. Join with flowers:
bouquet_id | variety_id | color
1 | 1 | yellow
1 | 1 | white
2 | 1 | pink
2 | 1 | purple
3. Join with flower_varieties:
name | price | variety
Get Well Soon | 59.99 | Carnation
Get Well Soon | 59.99 | Carnation
Mother's Day | 39.99 | Carnation
Mother's Day | 39.99 | Carnation
4. After DISTINCT:
name | price
Get Well Soon | 59.99
Mother's Day | 39.99
5. After ORDER BY and LIMIT:
name | price
Get Well Soon | 59.99
Here are other ways to write this query:
-- Using EXISTS
SELECT name, price
FROM bouquets b
WHERE EXISTS (
SELECT 1
FROM flowers f
JOIN flower_varieties v ON f.variety_id = v.id
WHERE f.bouquet_id = b.id
AND v.variety = 'Carnation'
)
ORDER BY name
LIMIT 1;
-- Using a subquery in WHERE
SELECT name, price
FROM bouquets
WHERE id IN (
SELECT DISTINCT bouquet_id
FROM flowers f
JOIN flower_varieties v ON f.variety_id = v.id
WHERE v.variety = 'Carnation'
)
ORDER BY name
LIMIT 1;
When writing queries like this, watch out for:
This query is optimized because: