効率を上げるために、レシピの材料の数をレシピテーブルに保存することをお勧めします(毎回この情報を計算する必要がない場合は、クエリが高速になります)。これは非正規化であり、データの整合性には悪影響しますが、パフォーマンスには影響します。レシピが更新された場合、これによりデータの不整合が発生する可能性があることに注意する必要があります。また、関連するすべての場所で番号が更新されていることを確認するように注意しないでください。レシピテーブルでing_countとして設定された新しい列を使用してこれを行ったと仮定しました。
NAME1、NAME2などの値がユーザー入力を介して提供されている場合は、必ずエスケープしてください。そうしないと、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
レシピ数を保存したくない場合は、次のようにすることができます。
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