【问题标题】:MySQL join 3 tables, with multiple columns excluding results from one tableMySQL连接3个表,多列不包括一个表的结果
【发布时间】:2018-01-09 23:46:39
【问题描述】:

我正在尝试在 MySQL 中加入 3 个表,需要一些帮助。

我的第一张表是食谱列表。

**recipes**
RecipeID | RecipeName
1        | Cheese and Ham Toasty
2        | 20 Minute Pasta
3        | Minute Steak

第二个表是分配给食谱表的成分列表

**ingredients**
RecipeID | IngredientID | IngredientName
1        | 1            | Cheese
1        | 2            | Bread
1        | 3            | Ham
1        | 4            | Butter
2        | 5            | Pasta
2        | 6            | Mince
2        | 1            | Cheese
3        | 8            | Steak
3        | 9            | BBQ Sauce

第三个表格是用户可以用来添加他们不想看到的配方的成分的表格,目前只有一种成分可供用户使用

**usersList**
IngredientID | userID
1            | 2

我加入表格时的结果应该如下:

**recipes**
RecipeID | RecipeName
3        | Minute Steak

但是,我的结果要么是所有我不想要的食谱,要么是一个空结果。下面是我正在使用的 MySQL,它为我提供了所有我不想要的食谱。

SELECT RecipeID, RecipeName FROM recipes LEFT JOIN ingredients
INNER JOIN usersList ON ingredients.IngredientID = usersList.IngredientID 
ON recipes.RecipeID = ingredients.RecipeID
WHERE recipes.RecipeID IS NOT NULL
AND usersList.userID = 2
GROUP BY recipes.RecipeID

如何加入这些表,以便获得不包含用户列表中包含任何成分的任何食谱的所有食谱,并且如果用户没有列出任何成分,仍能提供结果?提前感谢您的帮助。

【问题讨论】:

  • 附注:您的数据库未标准化,这可能会导致未来出现问题。应该有一个成分表,其中每种成分有一条记录(例如 ID 1 = 奶酪)和一个将食谱 (recipeid) 与其成分 (ingredientid) 链接起来的 recipe_ingredient 表。
  • 只是关于您的表结构的建议:鉴于您可能有许多与多个不同食谱相关的相同成分,从成分表中删除这种关系(规范化)是明智的。使用交叉引用(连接)表更好地建模多对多关系:en.wikipedia.org/wiki/Associative_entity
  • 谢谢 我知道上面的成分表有问题。我确实有 2 个成分表,但对于这个问题,我只是想稍微简化一下。感谢您的建议,它肯定会帮助其他人。

标签: mysql join


【解决方案1】:

您不是在寻找加入。您想查看不存在某种成分的食谱。所以从配方表中选择并在WHERE 子句中使用NOT EXISTSNOT IN 限制结果。这是一个带有两个IN 子句的简单解决方案:

select *
from recipes
where recipeid not in
(
  select recipeid
  from ingredients
  where ingredientid in
  (
    select ingredientid 
    from userslist
    where userid = 2
  )
);

【讨论】:

  • 谢谢托尔斯滕。我不知道为什么我一直在考虑加入表格。这真的简单多了。真的很感谢磨坊。
【解决方案2】:

在食谱和配料之间使用内连接,在配料和用户列表之间使用左连接,然后在从用户列表返回的主键不为空的排除结果中。

此输出将包括具有多种成分的食谱的多个条目-可能需要整理....

SELECT recipename, GROUP_CONCAT(ingredient_name), 
  SUM(IF(userlist.ingredientid IS NULL, 0, 1))
FROM recipes
INNER JOIN ingredients
ON recipes.recipeid=ingredients.ingredientid
LEFT JOIN userlist
ON ingredients.ingredientid=userlist.ingredientid
AND userlist.userid=_______
GROUP BY recipename
HAVING SUM(IF(userlist.ingredientid IS NULL, 0, 1))=0

【讨论】:

    【解决方案3】:

    您也可以在这里使用左连接,如下所示:

    select r.RecipeID, r.RecipeName from recipes r
    left join (select RecipeID from ingredients i
              join  usersList u on u.RecipeID = i.RecipeID) as u
              on u.RecipeID = r.RecipeID
    where u.RecipeID is null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多