我有3個表:SQL Server 2008中,如何檢查是否在數據庫中存在多條記錄?
- 配方:
- ID,名稱
- 成分:
- ID,名稱
- recipeingredient:
- ID,recipeId,ingredientId,數量
每一次,客戶創建一個新的配方,我需要檢查recipeingredient
表來驗證這個方子存在與否。如果ingredientId
和quantity
是完全一樣的,我會告訴配方已經存在的客戶。由於我需要檢查多行,需要幫助來編寫此查詢。
我有3個表:SQL Server 2008中,如何檢查是否在數據庫中存在多條記錄?
每一次,客戶創建一個新的配方,我需要檢查recipeingredient
表來驗證這個方子存在與否。如果ingredientId
和quantity
是完全一樣的,我會告訴配方已經存在的客戶。由於我需要檢查多行,需要幫助來編寫此查詢。
瞭解您的成分和數量,你可以做這樣的事情:
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
我原本以爲下面的查詢將查找菜譜的對,具有完全相同的成分:
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
如果你有一個新的配方,你可以修改這個查詢只尋找配方中的一個表(比如RI1)使用附加條件在on
條款。
如果將食材在一個臨時表中,可以替代這些表中的一個,說RI1,新表。
經過測試,我無法讓它工作。 –
@TimLehner。 。 。你能詳細說明數據的錯誤還是問題? –
當然,只要用我的答案數據(與您的方向基本相同)進行試用即可。然後更改數量。或者添加/刪除一行。你的'group by'可能實際上掩蓋了食譜之間的差異。 –
你可以嘗試這樣的事情找到,如果你有一個重複:
-- 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的「新」表。這樣,您在搜索之前不必插入新記錄。您也可以插入基表中,根據結果將所有內容包含在事務中並進行回滾。
你怎麼代表了新的配方?它是在同一張表中,在臨時表中還是在內存中? –
@ GordonLinoff我假設這是一個表單發佈......但很好的問題。 – RedFilter
是的,這是一個表格帖子 – qinking126