我有3张桌子:
每次客户创建新配方时,我都需要检查recipeingredient
表以验证此配方是否存在。如果ingredientId
和quantity
完全相同,我会告诉客户配方已经存在。由于我需要检查多行,因此需要帮助来编写此查询。
答案 0 :(得分:2)
了解您的成分和数量,您可以这样做:
select recipeId as ExistingRecipeID
from recipeingredient
where (ingredientId = 1 and quantity = 1)
or (ingredientId = 8 and quantity = 1)
or (ingredientId = 13 and quantity = 1)
group by recipeId
having count(*) = 3 --must match # of ingeredients in WHERE clause
答案 1 :(得分:2)
我原本以为以下查询会找到具有完全相同成分的食谱配对:
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
但是,此查询不能正确计算事物,因为不匹配没有正确的id对。唉。
以下 执行正确的比较。它在连接之前计算每个配方中的成分,因此可以在所有匹配的行上比较该值。
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(*)
having
子句保证每个配方的成分数量相同,并且匹配成分的数量是总数。这一次,我已经根据以下数据对其进行了测试:
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
如果你有一个新的配方,你可以修改这个查询,只需在on
子句中使用附加条件在其中一个表(比如ri1)中查找配方。
如果您将成分放在临时表中,您可以用新表替换其中一个表,例如ri1。
答案 2 :(得分:0)
您可以尝试这样的方法来查找是否有重复内容:
-- Setup test data
declare @recipeingredient table (
id int not null primary key identity
, recipeId int not null
, ingredientId int not null
, quantity int not null
)
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
-- Actual Query
if exists (
select *
from @recipeingredient old
full outer join @recipeingredient new
on old.recipeId != new.recipeId -- Different recipes
and old.ingredientId = new.ingredientId -- but same ingredients
and old.quantity = new.quantity -- and same quantities
where old.id is null -- Match not found
or new.id is null -- Match not found
)
begin
select cast(0 as bit) as IsDuplicateRecipe
end
else begin
select cast(1 as bit) as IsDuplicateRecipe
end
由于这实际上只是在搜索重复内容,因此您可能希望将临时表或pass a table variable替换为“新”表。这样,您无需在进行搜索之前插入新记录。您还可以插入基表,将整个事物包装在事务中并根据结果回滚。