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 - IN(...)优化问题中的“选择”查询(=>分层查询)