简体   繁体   English

在 SQL、Select 中,来自一对多表的所有 FK,其中 FK 的表数据存在于每个列表/连接中

[英]In SQL, Select all FKs from one-to-many table where table data for FK Exists in each of several lists/joins

My database has recipes with associated data (within a range of categories, each recipe has [0 - many] options selected for each category).我的数据库有带有关联数据的食谱(在一系列类别中,每个食谱都有为每个类别选择的 [0 - 许多] 选项)。 To search the recipes, a user can select [0 - many] options from [0 - many] categories.要搜索食谱,用户可以 select [0 - 许多] 类别中的 [0 - 许多] 选项。

I'm trying to construct a stored procedure that returns all RecipeIDs that match at least one OptionID for each Category where the user selected at least one OptionID.我正在尝试构建一个存储过程,该过程返回与用户选择至少一个 OptionID 的每个类别的至少一个 OptionID 匹配的所有 RecipeID。

So - if you want to find all main dishes and desserts with fruit, the proc needs to return all RecipeIDs where:所以 - 如果您想找到所有主菜和带水果的甜点,proc 需要返回所有 RecipeIDs,其中:

  • in RecipeData, for all entries with the same RecipeID (for all Options for a single Recipe)在 RecipeData 中,对于具有相同 RecipeID 的所有条目(对于单个 Recipe 的所有选项)
    • at least one OptionID is for 'Main Dish' OR at least one OptionID is for 'Dessert'至少一个 OptionID 用于“主菜”或至少一个 OptionID 用于“甜点”
    • AND at least one OptionID is for 'Fruit'并且至少有一个 OptionID 用于“水果”
    • AND ignore 'Ranking' (user didn't select any Options in this Category)并忽略“排名”(用户没有 select 此类别中的任何选项)

The number of Categories is finite and limited (currently 12).类别的数量是有限的(目前是 12 个)。 Right now, I have the user's search query supplied as 12 table variables - one for each Category, listing the selected OptionIDs for that Category.现在,我将用户的搜索查询作为 12 个表变量提供 - 每个类别一个,列出该类别的选定 OptionID。 I'd prefer to submit the user's search query to the proc as a single table, but I'm not sure if that would be possible.我更愿意将用户的搜索查询作为单个表提交给 proc,但我不确定这是否可行。 Regardless, that's a lower priority.无论如何,这是一个较低的优先级。

It must be possible to construct a query to return what I'm looking for, but I have no idea how to do this.必须可以构造一个查询来返回我正在寻找的内容,但我不知道该怎么做。 Everything I can think of involves looping through groups (RecipeData for each Recipe, Options for each Category), and from what I know, SQL isn't built to do this.我能想到的一切都涉及循环组(每个食谱的 RecipeData,每个类别的选项),据我所知,SQL 不是为此而构建的。

Can I do this in SQL, or will I have to do this in my C# code?我可以在 SQL 中执行此操作,还是必须在我的 C# 代码中执行此操作? If I can do this in SQL - how?如果我可以在 SQL 中做到这一点 - 怎么做?

Parameters:参数:

DECLARE @MealTypeOptionID TABLE ( OptionID INT )
DECLARE @IngredientOptionID TABLE ( OptionID INT )
DECLARE @RankingOptionID TABLE ( OptionID INT )

-- all 'Main Dish' or 'Dessert' recipes that have 'Fruit'
INSERT INTO @MealTypeOptionID (OptionID) VALUES (1), (2)
INSERT INTO @IngredientOptionID (OptionID) VALUES (4)

Tables:表:

Recipe
---------------------------------------------------------------
RecipeID    RecipeName
---------------------------------------------------------------
1           'Apple Pie'
2           'Blueberry Ice Cream'
3           'Brownies'
4           'Tuna Casserole'
5           'Pork with Apples'
6           'Fruit Salad'

Category
---------------------------------------------------------------
CategoryID    CategoryName
---------------------------------------------------------------
1             'Meal Type'
2             'Ingredients'
3             'Ranking'

Option
---------------------------------------------------------------
OptionID    CategoryID    OptionName
---------------------------------------------------------------
1           1             'Main Dish'
2           1             'Dessert'
3           1             'Side Dish'
4           2             'Fruit'
5           2             'Meat'
6           3             'Meh'
7           3             'Great'

RecipeData
---------------------------------------------------------------
RecipeDataID    RecipeID    OptionID
---------------------------------------------------------------
1               1           2
2               1           4
3               1           7
4               2           2
5               2           4
6               3           2
7               4           1
8               4           5
9               4           6
10              5           1
11              5           4
12              5           5
13              6           3
14              6           4

My solution:我的解决方案:

-- @optionsToInclude is a parameter of the proc
DECLARE @optionsToInclude TABLE (CategoryID INT, OptionID INT)

-- result table
DECLARE @recipeIDs TABLE (RecipeID INT)

-- get CategoryID FOR first select
DECLARE @categoryID INT
SELECT TOP 1 @categoryID = CategoryID FROM @optionsToInclude GROUP BY CategoryID

-- insert into result table all RecipeIDs that contain any OptionIDs within CategoryID
INSERT INTO @recipeIDs (RecipeID)
SELECT DISTINCT d.RecipeID
FROM RecipeData d
INNER JOIN @optionsToInclude c
    ON c.CategoryID = @categoryID
    AND c.OptionID = d.OptionID

-- delete from @optionsToInclude all entries where CategoryID = @categoryID
DELETE FROM @optionsToInclude WHERE CategoryID = @categoryID

-- check if any more Categories exist to loop through
DECLARE @exists BIT = 1

IF (NOT EXISTS (SELECT * FROM @optionsToInclude))
    SET @exists = 0

WHILE @exists = 1
BEGIN

    -- get CategoryID for select
    SELECT TOP 1 @categoryID = CategoryID FROM @optionsToInclude GROUP BY CategoryID

    -- delete from result table all RecipeIDs that do not contain any OptionIDs within CategoryID
    DELETE FROM @recipeIDs
    WHERE RecipeID NOT IN
    (
        SELECT DISTINCT d.RecipeID
        FROM dbo.RecipeData d
        INNER JOIN @optionsToInclude i
            ON i.CategoryID = @categoryID
            AND i.OptionID = d.OptionID
    )

    -- delete from @optionsToInclude all entries where CategoryID = @categoryID
    DELETE FROM @optionsToInclude WHERE CategoryID = @categoryID

    -- check if any more Categories exist to loop through
    IF (NOT EXISTS (SELECT * FROM @optionsToInclude))
        SET @exists = 0

END

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 一对多表中的sql选择 - sql selection from one-to-many table 忽略与一对多表在JOIN上匹配的所有希拉希数据 - Omiting all heirachy data that matches on a JOIN with a one-to-many table 对具有 where 条件的一对多表使用连接的 SQL 查询 - SQL query using joins for one to many table having a where condition 如何从多对多表中选择一个ID,而另一个ID中不存在的记录呢? - How to select a record from a many to many table where one id exists in one but not another? SQL:表格包含单个项目,并在列表中添加FK-返回表格和列表中的所有单个项目 - SQL: table contains individual items and FK to lists - return all individual items from table & lists 从表A中选择要连接到表B中所有数据的位置 - Selecting from Table A where it joins to all data in Table B 如何代表具有几个一对多关系的表 - How to represent a table with several one-to-many relationships 选择具有一对多关系的记录,其中所有记录都在列表中 - Select records with one-to-many relationship where all of the many are in a list 查找一对多联接表满足一个条件但不满足另一个条件的所有记录 - Find all records where one-to-many join table satisfies one condition, but not another condition 从一个表中选择在另一个表中存在映射的行 - Select rows from one table where mapping exists in another table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM