查询一对多关系SQL

时间:2018-07-13 02:14:43

标签: sql

我有这些桌子

Table FoodName - Table FoodIngredients - Table FoodDescrip     
  ID | Name    -    ID | Ingredient    - ID | Descrip | IDFoodN | IDIngred
  01 |  A      -   001 |    AA         - 01 |   abcb  |   01    |  001
  02 |  B      -   002 |    BB         - 02 |   abcb  |   01    |  002
                   003 |    CC           03 |   abcb  |   01    |  003
                                         04 |   abcb  |   02    |  001
                                         05 |   abcb  |   02    |  003

我尝试过

Select 
  f.Name 
From 
  f.FoodName 
INNER JOIN 
  FoodDescrip D ON f.ID = D.ID 
INNER JOIN 
  FoodIngredients I ON I.ID = D.ID 
WHERE 
  Ingredient LIKE NOT ='BB'"

我需要知道不含BB成分的食物,但我需要按成分名称而不是ID进行搜索。我试图使用“成分不喜欢”,但它不起作用。 (我正在使用内联接)

3 个答案:

答案 0 :(得分:2)

一种方法使用条件聚合来检查成分:

SELECT
    f1.ID, f1.Name
FROM FoodName f1
INNER JOIN FoodDescrip f2
    ON f1.ID = f2.IDFoodN
INNER JOIN FoodIngredients f3
    ON f2.IDIngred = f3.ID
GROUP BY
    f1.ID, f1.Name
HAVING
    SUM(CASE WHEN f3.Ingredient = 'BB' THEN 1 ELSE 0 END) = 0

答案 1 :(得分:1)

对此我将使用“不存在”。 (或者不像AB_87的答案那样输入。)您的FoodDescrip表是食物和配料之间的交叉引用。您想要每种与BB成分没有交叉引用的食物。

SELECT f.Name 
FROM FoodName f 
WHERE NOT EXISTS 
(
    SELECT * 
    FROM FoodDescrip d 
    JOIN FoodIngredients i ON i.ID = d.IDIngred 
    AND i.Ingredient = ‘BB’
    AND d.IDFoodN = f.ID
)

“选择所有我们不存在的食物与BB成分之间的交叉引用。”

外部查询从食物表中选择,因此您可以返回食物名称。 NOT EXISTS中的子查询从交叉引用表连接到成分表,因此您可以找到带有BB名称的子查询,并且也将其过滤为仅包含外部查询中的食物。因此,如果在与食物链接的子查询中发现任何BB,则NOT EXISTS将为false,并且WHERE子句将从结果中删除食物。

可以稍作调整,以使用NOT IN代替NOT EXISTS。基本上是完全一样的方法。就是这样:

SELECT f.Name 
FROM FoodName f 
WHERE f.ID NOT IN 
(
    SELECT d.IDFoodN
    FROM FoodDescrip d 
    JOIN FoodIngredients i ON i.ID = d.IDIngred 
    AND i.Ingredient = ‘BB’
)

“选择ID不在与交叉参考表中的BB成分链接的食品ID列表中的所有食品。”

与Tim的方法相比,我更喜欢这些方法,因为我认为它们读起来更好。而且,它们的性能可能更好,因为一旦找到一种与BB成分相关的成分,他们就可以从结果中剔除食物。蒂姆的条件汇总方法要求计算所有匹配项,并查看结果是否等于vs.大于零。

答案 2 :(得分:1)

您可以尝试一下。获取具有成分“ BB”的FoodId,然后检索所有之前未检索到FoodId的食物。

SELECT *
FROM   FoodName
WHERE  ID NOT IN (   SELECT d.IDFoodN
                     FROM   FoodIngredients i
                            JOIN FoodDescrip d ON i.ID = d.IDIngred
                     WHERE  i.Ingredient = 'BB' );