我有这些桌子
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进行搜索。我试图使用“成分不喜欢”,但它不起作用。 (我正在使用内联接)
答案 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' );