Sugeriría almacenar el recuento de la cantidad de ingredientes para la receta en la tabla de recetas, solo por el bien de la eficiencia (hará que la consulta sea más rápida si no tiene que calcular esta información cada vez). Esta es la desnormalización, que es mala para la integridad de los datos pero buena para el rendimiento. Debe tener en cuenta que esto puede causar inconsistencias en los datos si las recetas se actualizan y no tiene cuidado de asegurarse de que el número se actualice en todos los lugares relevantes. Supuse que había hecho esto con la nueva columna configurada como ing_count en la tabla de recetas.
Asegúrese de escapar de los valores de NOMBRE1, NOMBRE2, etc. si se proporcionan a través de la entrada del usuario; de lo contrario, corre el riesgo de inyecció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
Si no desea almacenar el recuento de recetas, puede hacer algo como esto:
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