Sugerowałbym przechowywanie liczby składników dla przepisu w tabeli przepisów, tylko ze względu na wydajność (przyspieszy to zapytanie, jeśli nie będzie musiało za każdym razem obliczać tych informacji). Jest to denormalizacja, która jest zła dla integralności danych, ale dobra dla wydajności. Należy mieć świadomość, że może to spowodować niespójność danych, jeśli receptury zostaną zaktualizowane i nie należy dbać o to, aby liczba była aktualizowana w każdym odpowiednim miejscu. Założyłem, że zrobiłeś to z nową kolumną ustawioną jako ing_count w tabeli przepisów.
Upewnij się, że pomijasz wartości dla NAME1, NAME2 itd., jeśli są one dostarczane przez dane wejściowe użytkownika — w przeciwnym razie istnieje ryzyko wstrzyknięcia 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
Jeśli nie chcesz przechowywać liczby przepisów, możesz zrobić coś takiego:
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