【问题标题】:mysql query where not with Hierarchical tablesmysql查询不使用分层表的地方
【发布时间】:2011-04-24 05:20:08
【问题描述】:

所以基本上我将 3 个表连接在一起。主表是菜谱,然后是配料表,然后是配料表。

所以我需要一个查询,其中只有不含鸡肉的食谱。我遇到的问题是,因为当我使用 where != 时食谱有很多成分,这只是去除了该肉的成分,但留下了其他成分.....我如何解释多种成分。

select Recipe.name as "No chicken"  from Recipe inner join IngredientList on Recipe.recipeId=IngredientList.recipeId inner join Ingredients on IngredientList.IngredientId=Ingredients.ingredientId where type!="chcicken" group by Recipe.name;

【问题讨论】:

  • 另外,如果我只想要鸡肉......所以 type="chicken" 并且只产生鸡肉食谱?

标签: mysql


【解决方案1】:

您的原始语句有一个 GROUP BY 没有聚合函数。那没有意义。如果您尝试排序,它应该是ORDER BY

试试这样的:

SELECT `Recipe`.`name` AS "No chicken"
FROM `Recipe`
WHERE `Recipe`.`RecipeId` NOT IN (
    SELECT DISTINCT `IngredientList`.`RecipeId` AS `RecipeID`
    FROM `IngredientList`
        INNER JOIN `Ingredients` ON `IngredientList`.`IngredientId` = `Ingredients`.`IngredientId`
    WHERE `Ingredients`.`Type` = 'chicken'
)
ORDER BY `Recipe`.`name`

根据您的架构,如果您获得重复的配方名称,您可能需要在主选择语句中使用 SELECT DISTINCT

【讨论】:

    【解决方案2】:

    上面有一些错别字,但 Amirshk 有一个逻辑上正确的答案。

    但是,我建议避免在 MySQL 中使用 IN() 和 NOT IN() 子句,因为它们在与大型配方数据库一样大的一组表上非常非常慢。 IN 和 NOT IN 可以重写为连接,以将运行时间减少到 MySQL 5.0 中时间的 1/100。即使 MySQL 5.5 有了很大的改进,等效的 JOIN 查询在大型表上的基准测试时间也只有 1/5。

    这是修改后的查询:

    SELECT
    Recipe.name AS "No Chicken"
    FROM Recipe LEFT JOIN
        (
        SELECT IngredientList.recipeId, Ingredients.ingredientId
        FROM IngredientList JOIN Ingredients USING (IngredientId)
        WHERE Ingredients.type = 'chicken'
        ) WithChicken
        ON Recipe.recipeId = WithChicken.recipeId
    WHERE WithChicken.recipeId IS NULL;
    

    这很迟钝,所以这里是简化的 SQL,它提供了 NOT IN(...) 等效排除连接的关键概念:

    SELECT whatever FROM x
    WHERE x.id NOT IN (
        SELECT id FROM y
    };
    

    变成

    SELECT whatever FROM x
    LEFT JOIN y ON x.id = y.id
    WHERE y.id IS NULL;
    

    【讨论】:

      【解决方案3】:

      使用内部查询过滤包含鸡肉的食谱,然后选择所有不包含鸡肉的食谱。

      这样:

      select
          Recipe.name as "No chicken"
          from Recipe
              inner join IngredientList on Recipe.recipeId=IngredientList.recipeId
              inner join Ingredients on IngredientList.IngredientId=Ingredients.ingredientId
          where Recipe.recipeId NOT IN (
              select
              Recipe.recipeId
              from Recipe
                  inner join IngredientList on Recipe.recipeId=IngredientList.recipeId
                  inner join Ingredients on IngredientList.IngredientId=Ingredients.ingredientId
                  type ="chcicken" group by Recipe.recipeId)
      

      【讨论】:

        猜你喜欢
        • 2020-12-27
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2011-06-26
        • 2011-08-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多