Hãy xem xét ví dụ này ...
SELECT * FROM recipes;
+-----------+---------------------------------+
| recipe_id | recipe |
+-----------+---------------------------------+
| 6 | Beans & Macaroni |
| 9 | Beans on Jacket Potato |
| 3 | Beans on Toast |
| 10 | Cheese & Beans on Jacket Potato |
| 4 | Cheese & Beans on Toast |
| 2 | Cheese on Toast |
| 1 | Macaroni & Cheese |
| 12 | Peanut Butter on Toast |
| 5 | Toast & Jam |
+-----------+---------------------------------+
SELECT * FROM recipe_ingredient;
+-----------+---------------+
| recipe_id | ingredient_id |
+-----------+---------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 2 | 4 |
| 3 | 3 |
| 3 | 4 |
| 4 | 2 |
| 4 | 3 |
| 4 | 4 |
| 5 | 4 |
| 5 | 5 |
| 6 | 1 |
| 6 | 3 |
| 9 | 3 |
| 9 | 6 |
| 10 | 2 |
| 10 | 3 |
| 10 | 6 |
| 12 | 4 |
| 12 | 7 |
+-----------+---------------+
SELECT * FROM ingredients;
+---------------+---------------+
| ingredient_id | ingredient |
+---------------+---------------+
| 3 | Beans |
| 2 | Cheese |
| 6 | Jacket Potato |
| 5 | Jam |
| 1 | Macaroni |
| 7 | Peanut Butter |
| 4 | Toast |
+---------------+---------------+
Phần sau trả về danh sách tất cả các công thức nấu ăn và các thành phần cần thiết để tạo ra chúng ...
SELECT r.*
, i.*
FROM recipes r
JOIN recipe_ingredient ri
ON ri.recipe_id = r.recipe_id
JOIN ingredients i
ON i.ingredient_id = ri.ingredient_id;
+-----------+---------------------------------+---------------+---------------+
| recipe_id | recipe | ingredient_id | ingredient |
+-----------+---------------------------------+---------------+---------------+
| 6 | Beans & Macaroni | 1 | Macaroni |
| 6 | Beans & Macaroni | 3 | Beans |
| 9 | Beans on Jacket Potato | 3 | Beans |
| 9 | Beans on Jacket Potato | 6 | Jacket Potato |
| 3 | Beans on Toast | 3 | Beans |
| 3 | Beans on Toast | 4 | Toast |
| 10 | Cheese & Beans on Jacket Potato | 2 | Cheese |
| 10 | Cheese & Beans on Jacket Potato | 3 | Beans |
| 10 | Cheese & Beans on Jacket Potato | 6 | Jacket Potato |
| 4 | Cheese & Beans on Toast | 2 | Cheese |
| 4 | Cheese & Beans on Toast | 3 | Beans |
| 4 | Cheese & Beans on Toast | 4 | Toast |
| 2 | Cheese on Toast | 2 | Cheese |
| 2 | Cheese on Toast | 4 | Toast |
| 1 | Macaroni & Cheese | 1 | Macaroni |
| 1 | Macaroni & Cheese | 2 | Cheese |
| 12 | Peanut Butter on Toast | 4 | Toast |
| 12 | Peanut Butter on Toast | 7 | Peanut Butter |
| 5 | Toast & Jam | 4 | Toast |
| 5 | Toast & Jam | 5 | Jam |
+-----------+---------------------------------+---------------+---------------+
Bây giờ, giả sử chúng ta có một phòng đựng thức ăn chứa Phô mai, Đậu và Bánh mì nướng. Chúng ta có thể xây dựng những gì CHỈ bằng những thành phần đó?
SELECT r.*
, SUM(CASE WHEN ingredient IN ('Cheese','Beans','Toast') THEN 1 ELSE 0 END) x
, COUNT(*) y
FROM recipes r
JOIN recipe_ingredient ri ON ri.recipe_id = r.recipe_id
JOIN ingredients i ON i.ingredient_id = ri.ingredient_id
GROUP
BY r.recipe_id;
+-----------+---------------------------------+------+---+
| recipe_id | recipe | x | y |
+-----------+---------------------------------+------+---+
| 1 | Macaroni & Cheese | 1 | 2 |
| 2 | Cheese on Toast | 2 | 2 | <--
| 3 | Beans on Toast | 2 | 2 | <--
| 4 | Cheese & Beans on Toast | 3 | 3 | <-- *
| 5 | Toast & Jam | 1 | 2 |
| 6 | Beans & Macaroni | 1 | 2 |
| 9 | Beans on Jacket Potato | 1 | 2 |
| 10 | Cheese & Beans on Jacket Potato | 2 | 3 |
| 12 | Peanut Butter on Toast | 1 | 2 |
+-----------+---------------------------------+------+---+
x = y : recipes use only those ingredients found in the pantry.
x = y = total no of ingredients in pantry : recipes using EXACTLY the ingredients found in the pantry
Do đó, điều này có thể được viết lại ...
SELECT r.*
FROM recipes r
JOIN recipe_ingredient ri ON ri.recipe_id = r.recipe_id
JOIN ingredients i ON i.ingredient_id = ri.ingredient_id
GROUP
BY r.recipe_id
HAVING SUM(CASE WHEN ingredient IN ('Cheese','Beans','Toast') THEN 1 ELSE 0 END) = COUNT(*);