Je suggérerais de stocker le nombre d'ingrédients pour la recette dans la table de recettes, juste pour des raisons d'efficacité (cela rendra la requête plus rapide si elle n'a pas à calculer cette information à chaque fois). C'est la dénormalisation, qui est mauvaise pour l'intégrité des données mais bonne pour les performances. Vous devez être conscient que cela peut entraîner des incohérences de données si les recettes sont mises à jour et que vous ne veillez pas à ce que le numéro soit mis à jour à chaque endroit pertinent. J'ai supposé que vous l'aviez fait avec la nouvelle colonne définie comme ing_count dans la table de recettes.
Assurez-vous d'échapper les valeurs dans pour NAME1, NAME2, etc. si elles sont fournies via une entrée utilisateur - sinon vous risquez une injection 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
Si vous ne souhaitez pas stocker le nombre de recettes, vous pouvez faire quelque chose comme ceci :
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