Je pensais à l'origine que la requête suivante trouver des paires de recettes qui ont exactement les mêmes ingrédients:
select ri1.recipeId, ri2.recipeId
from RecipeIngredient ri1 full outer join
RecipeIngredient ri2
on ri1.ingredientId = ri2.ingredientId and
ri1.quantity = ri2.quantity and
ri1.recipeId < ri2.recipeId
group by ri1.recipeId, ri2.recipeId
having count(ri1.id) = count(ri2.id) and -- same number of ingredients
count(ri1.id) = count(*) and -- all r1 ingredients are present
count(*) = count(ri2.id) -- all r2 ingredents are present
Cependant, cette requête ne compte pas les choses correctement, car les discordances n'ont pas les bonnes paires d'identifiants. Hélas.
Le fait la comparaison correcte. Il compte les ingrédients dans chaque recette avant la jointure, donc cette valeur peut simplement être comparée sur toutes les rangées correspondantes.
select ri1.recipeId, ri2.recipeId
from (select ri.*, COUNT(*) over (partition by recipeid) as numingredients
from @RecipeIngredient ri
) ri1 full outer join
(select ri.*, COUNT(*) over (partition by recipeid) as numingredients
from @RecipeIngredient ri
) ri2
on ri1.ingredientId = ri2.ingredientId and
ri1.quantity = ri2.quantity and
ri1.recipeId < ri2.recipeId
group by ri1.recipeId, ri2.recipeId
having max(ri1.numingredients) = max(ri2.numingredients) and
max(ri1.numingredients) = count(*)
La clause having
garantit que chaque recette que le même nombre de composants, et que le nombre de composants correspondant est total. Cette fois, je l'ai testé sur les données suivantes:
insert into @recipeingredient select 1, 1, 1
insert into @recipeingredient select 1, 2, 10
insert into @recipeingredient select 2, 1, 1
insert into @recipeingredient select 2, 2, 10
insert into @recipeingredient select 2, 3, 10
insert into @recipeingredient select 3, 1, 1
insert into @recipeingredient select 4, 1, 1
insert into @recipeingredient select 4, 3, 10
insert into @recipeingredient select 5, 1, 1
insert into @recipeingredient select 5, 2, 10
Si vous avez une nouvelle recette, vous pouvez modifier cette requête à regarder juste pour la recette dans l'une des tables (par exemple ri1) en utilisant une somme supplémentaire condition sur la clause on
.
Si vous placez les ingrédients dans une table temporaire, vous pouvez remplacer l'une de ces tables, disons ri1, par la nouvelle table.
Comment représentez-vous la nouvelle recette? Est-ce dans les mêmes tables, dans les tables temporaires, en mémoire? –
@GordonLinoff Je suppose que c'est un post de formulaire ... mais bonne question. – RedFilter
oui, c'est un poste – qinking126