MySQL:如果并非所有行值都为真,则排除子集

时间:2015-04-11 18:14:50

标签: mysql

我有三个MySQL表:ingredientsingredient_in_reciperecipes可以INNER JOIN来获取食谱中的成分。此外,ingredients表格还有一列vegetarian。我想得到所有被认为是素食的食谱,这意味着给定食谱的所有成分必须将vegetarian设置为1(它是BOOL / {{1} })。

我查看了使用tinyint(1)ALL和其他各种内容的查询,但我找不到可行的解决方案。做这个的最好方式是什么?是否有一些解决方案比其他解决方案更有效?

额外(仅相关)表信息:

HAVING NOT MAX

我的查询目前正在开始:

mysql> DESCRIBE ingredients;
+-----------------+---------------+------+-----+---------+----------------+
| Field           | Type          | Null | Key | Default | Extra          |
+-----------------+---------------+------+-----+---------+----------------+
| id              | int(11)       | NO   | PRI | NULL    | auto_increment |
| name            | varchar(100)  | NO   |     | NULL    |                |
| vegetarian      | tinyint(1)    | NO   |     | 0       |                |
+-----------------+---------------+------+-----+---------+----------------+

mysql> DESCRIBE ingredient_in_recipe;
+---------------+------------------------+------+-----+---------+-------+
| Field         | Type                   | Null | Key | Default | Extra |
+---------------+------------------------+------+-----+---------+-------+
| recipe_id     | int(11)                | NO   |     | NULL    |       |
| ingredient_id | int(11)                | NO   |     | NULL    |       |
+---------------+------------------------+------+-----+---------+-------+

mysql> DESCRIBE recipes;
+------------------------+----------------------+------+-----+---------+----------------+
| Field                  | Type                 | Null | Key | Default | Extra          |
+------------------------+----------------------+------+-----+---------+----------------+
| id                     | int(11)              | NO   | PRI | NULL    | auto_increment |
| name                   | text                 | NO   |     | NULL    |                |
+------------------------+----------------------+------+-----+---------+----------------+

所以我最后错过了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; WHEREALL或其他声明。

2 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

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
)

答案 1 :(得分:1)

这样想。

  1. 选择具有任何非植物成分的配方。
  2. 从所有食谱集中减去此集。
  3. 所以这里有一套非蔬菜成分的食谱。

        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
    

    注意:你为什么用tinyint标记一个boolen? USE布尔值标记布尔值。

    此外,您的数据库模型非常好。您的命名是一致且适当的。

    现在我们已经拥有了#ve;非vegitarian&#34;食谱,我们只是减去一个&#34; set&#34;透视[如在集理论中]。

    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
      );