MySQL:如果不是所有行值都为true,则排除子集
我有三个MySQL表:配料表、配方中的配料表和配方表,它们可以通过内部连接来获取配方中的配料。此外,配料表中有一列“素食者”。我想得到所有被认为是素食主义者的食谱,这意味着给定食谱的所有成分必须将素食主义者设置为1,这是一个BOOL/tinyint1 我研究过使用ALL的查询,没有MAX和其他各种东西,但我找不到有效的解决方案。最好的方法是什么?是否有比其他解决方案更有效的解决方案 仅附加相关表格信息: 我的查询的开始当前为:MySQL:如果不是所有行值都为true,则排除子集,mysql,Mysql,我有三个MySQL表:配料表、配方中的配料表和配方表,它们可以通过内部连接来获取配方中的配料。此外,配料表中有一列“素食者”。我想得到所有被认为是素食主义者的食谱,这意味着给定食谱的所有成分必须将素食主义者设置为1,这是一个BOOL/tinyint1 我研究过使用ALL的查询,没有MAX和其他各种东西,但我找不到有效的解决方案。最好的方法是什么?是否有比其他解决方案更有效的解决方案 仅附加相关表格信息: 我的查询的开始当前为: SELECT recipe.name, ingredient.nam
SELECT recipe.name, ingredient.name
FROM ingredients AS ingredient
INNER JOIN ingredient_in_recipe AS ir
ON ir.ingredient_id = ingredient.id
INNER JOIN recipes AS recipe
ON ir.recipe_id = recipe.id;
因此,我在结尾缺少WHERE、ALL、IN或something语句。您可以尝试以下方法:
SELECT r.name FROM recipes r WHERE r.id NOT IN (
SELECT ir.recipe_id FROM ingredient_in_recipe ir
INNER JOIN ingredients i ON ir.ingredient_id = i.id
WHERE i.vegeterian = 0
)
这样想吧 选择含有任何非素食成分的食谱。 从所有配方的集合中减去此集合。 这是一套含有非蔬菜成分的食谱
select
id
from
recipes,
ingredient_in_recipe,
ingredients
where
ingredient_in_recipe.recipe_id = recipes.id
and
ingredient_in_recipe.ingredient_id = ingredients.id
and
ingredients.vegetarian <> 1
注意:为什么你要用锡纸来标记布林?使用Boolean标记Boolean
你的DB模型也很好。您的命名是一致和适当的
既然我们有了非素食主义的食谱,我们就从集合论的角度进行减法
select
*
from
recipes
where
id NOT IN (
-- this subquery returns a set of IDs corresponding to non-vegitarian recipes.
select
id
from
recipes,
ingredient_in_recipe,
ingredients
where
ingredient_in_recipe.recipe_id = recipes.id
and
ingredient_in_recipe.ingredient_id = ingredients.id
and
ingredients.vegetarian <> 1
);
从性能的角度来看,我建议不要使用相关子查询,除非绝对必要。谢谢,这很好用。我以前没有使用过“不存在”或“不存在”,所以这是一个很好的解决方案。有关更详细的解释,请参见@Bret的答案。在这种情况下,使用=0而不是1会有问题吗?我确信素食者将为0 false或1 true。是的,最好使用0 Yes,替代查询也可以。这会稍微快一点,对吗?我不确定是否有区别。它将在没有任何限制的情况下工作。在任何一种情况下,我都会在配方中的配料中创建索引,在创建表时,我使用BOOL数据类型(转换为TINYINT1)在vegetrian上创建索引。至少,我相当肯定它是这样做的。无论如何,我们都会考虑这两种数据类型。这里有这样一句话:BOOL,BOOLEAN这些类型是TINYINT1的同义词。零的值被认为是错误的。非零值被认为是真的。这并不能完全起作用,因为查询中没有包含表配料。此表对配料和食谱之间的多对多关系进行排序。配料表不包含配方id字段,它位于配方中的配料中。我认为@JuniorCompressor的答案需要内部连接。
select
*
from
recipes
where
id NOT IN (
-- this subquery returns a set of IDs corresponding to non-vegitarian recipes.
select
id
from
recipes,
ingredient_in_recipe,
ingredients
where
ingredient_in_recipe.recipe_id = recipes.id
and
ingredient_in_recipe.ingredient_id = ingredients.id
and
ingredients.vegetarian <> 1
);