mysql查询不使用分层表的地方

Posted

技术标签:

【中文标题】mysql查询不使用分层表的地方【英文标题】:mysql query where not with Hierarchical tables 【发布时间】: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" 并且只产生鸡肉食谱? 【参考方案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)

【讨论】:

以上是关于mysql查询不使用分层表的地方的主要内容,如果未能解决你的问题,请参考以下文章

如何创建 MySQL 分层递归查询?

如何创建 MySQL 分层递归查询?

MySQL - IN(...)优化问题中的“选择”查询(=>分层查询)

使用分层数据结构对数据库进行分片

mysql啥时候使用子查询,啥时候使用表连接查询,关系多张表的时候该怎么查询

mysql 如何使用sql查询某一个表的表头