Tôi khuyên bạn nên lưu trữ số lượng nguyên liệu cho công thức trong bảng công thức, chỉ vì mục đích hiệu quả (nó sẽ làm cho truy vấn nhanh hơn nếu nó không phải tính toán thông tin này mỗi lần). Đây là hiện tượng không chuẩn hóa, không tốt cho tính toàn vẹn của dữ liệu nhưng lại tốt cho hiệu suất. Bạn nên biết rằng điều này có thể gây ra mâu thuẫn dữ liệu nếu công thức nấu ăn được cập nhật và bạn không cẩn thận để đảm bảo rằng số lượng được cập nhật ở mọi nơi có liên quan. Tôi cho rằng bạn đã làm điều này với cột mới được đặt là ing_count trong bảng công thức.
Đảm bảo rằng bạn thoát các giá trị trong NAME1, NAME2, v.v. nếu chúng được cung cấp thông qua đầu vào của người dùng - nếu không, bạn có nguy cơ bị chèn SQL.
select recipe.rid, recipe.recipe_name, recipe.ing_count, count(ri) as ing_match_count
from recipe_ingredients ri
inner join (select iid from ingredients where i.name='NAME1' or i.name='NAME2' or i.NAME='NAME3') ing
on ri.iid = ing.iid
inner join recipe
on recipe.rid = ri.rid
group by recipe.rid, recipe.recipe_name, recipe.ing_count
having ing_match_count = recipe.ing_count
Nếu bạn không muốn lưu trữ số lượng công thức, bạn có thể làm như sau:
select recipe.rid, recipe.recipe_name, count(*) as ing_count, count(ing.iid) as ing_match_count
from recipe_ingredients ri
inner join (select iid from ingredients where i.name='NAME1' or i.name='NAME2' or i.NAME='NAME3') ing
on ri.iid = ing.iid
right outer join recipe
on recipe.rid = ri.rid
group by recipe.rid, recipe.recipe_name
having ing_match_count = ing_count