选择名称,其中包含所有提及的值,并排除多对多关系中的重复项

时间:2019-03-24 03:38:06

标签: sql sql-server tsql relational-division

我对SQL还是很陌生,我正在建立一个配方数据库,该数据库从用户那里获取配料并根据配料查找配方。

我有一个SQL查询,该查询获取包含成分的配方名称,但是我需要它来选择包含所有成分并排除重复的配方。

" SELECT recipes.Name, recipes.Preperation_Time, recipes.Author FROM recipes" +
" INNER JOIN RecipeIngredients ON RecipeIngredients.Recipe_ID = recipes.Recipe_ID" +
" INNER JOIN Ingredients ON Ingredients.Ingredient_ID = RecipeIngredients.Ingredient_ID" +
" WHERE ingredients.Name IN (" + ingredientString + ")");

如果有帮助,这是我的桌子:

CREATE TABLE [dbo].[recipes]
(
    [Recipe_ID]        INT IDENTITY (1, 1) NOT NULL,
    [Name]             VARCHAR(MAX) NOT NULL,
    [Instructions]     TEXT         NULL,
    [Preperation_Time] FLOAT(53)    NULL,
    [Author]           VARCHAR(MAX) NULL,

    CONSTRAINT [PK.recipes] 
        PRIMARY KEY CLUSTERED ([Recipe_ID] ASC)
 );

CREATE TABLE [dbo].[RecipeIngredients] 
(
    [Recipe_ID]     INT NOT NULL,
    [Ingredient_ID] INT NOT NULL,

    PRIMARY KEY CLUSTERED ([Recipe_ID] ASC, [Ingredient_ID] ASC),
    CONSTRAINT [FK_RecipeIngredients_To_Ingredients] 
        FOREIGN KEY ([Ingredient_ID]) 
        REFERENCES [dbo].[Ingredients] ([Ingredient_ID]),
    CONSTRAINT [FK_RecipeIngredients_To_Recipes] 
        FOREIGN KEY ([Recipe_ID]) 
        REFERENCES [dbo].[recipes] ([Recipe_ID])
 );

CREATE TABLE [dbo].[Ingredients] 
(
    [Ingredient_ID] INT IDENTITY (1, 1) NOT NULL,
    [Name]          VARCHAR(50) NOT NULL,

    PRIMARY KEY CLUSTERED ([Ingredient_ID] ASC)
);

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用聚合。我建议将成分作为VALUES()列表而不是字符串来传递。但是,使用您的构造:

SELECT r.Name, r.Preperation_Time, r.Author
FROM recipes r LEFT JOIN
     RecipeIngredients ri
     ON ri.Recipe_ID = r.Recipe_ID LEFT JOIN
     Ingredients i
     ON i.Ingredient_ID = ri.Ingredient_ID AND
        i.Name IN (" + ingredientString + ")"
GROUP BY r.Name, r.Preperation_Time, r.Author
HAVING COUNT(*) = COUNT(i.Ingredient_Id);  -- all match