MySQL'AND'查询无法按预期工作

时间:2013-02-07 14:02:46

标签: mysql

我目前正在制作3张桌子。食谱,配料和配方。 这是经典的多种情况,有了recipeIng来解决这个问题。

然而,我无法获得我认为的那个,一个相当简单的'AND'查询。我想要实现的是一次寻找多种成分。例如:

SELECT r.recipeTitle AS recipe
FROM Recipe r
WHERE recipeID IN(
    SELECT r.recipeID
    FROM recipeIng il, Ingredient i
    WHERE (il.ingredientID = i.ingredientID)
    AND (il.recipeID = r.recipeID)
    AND (i.ING LIKE '%cheese%' AND i.ING LIKE '%salmon%')

);

查询运行时,它不输出任何内容。我似乎无法看到我在这里做错了什么。 任何帮助都会非常感激。

感谢。

3 个答案:

答案 0 :(得分:3)

所以基本上你想要包含你所查询的任何成分的食谱。这可以使用简单的直接连接来执行:

SELECT DISTINCT(r.recipeTitle) AS recipe
FROM Ingredient i
INNER JOIN recipeIng il ON il.ingredientID = i.ingredientID
INNER JOIN Recipe r ON r.recipeID = il.recipeID
WHERE i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%'

DISTINCT()确保您在两种成分中都没有看到相同的配方两次。

如果配方中必须包含两种成分,则必须使用AND代替OR

答案 1 :(得分:2)

首先,您可以大大简化查询,因为您不需要外部查询。以下是完全相同的:

SELECT r.recipeTitle AS recipe
FROM recipeIng il, Ingredient i, Recipe r
WHERE (il.ingredientID = i.ingredientID)
AND (il.recipeID = r.recipeID)
AND (i.ING LIKE '%cheese%' AND i.ING LIKE '%salmon%')

其次,你不需要所有这些括号。

SELECT r.recipeTitle AS recipe
FROM recipeIng il, Ingredient i, Recipe r
WHERE il.ingredientID = i.ingredientID
AND   il.recipeID = r.recipeID
AND   i.ING LIKE '%cheese%' 
AND i.ING LIKE '%salmon%'

第三,你应该INNER JOIN你的表,以使它们之间的关系更清晰:

SELECT r.recipeTitle AS recipe
FROM recipeIng il JOIN 
     Ingredient i ON  il.ingredientID = i.ingredientID JOIN
     Recipe r ON il.recipeID = r.recipeID
WHERE i.ING LIKE '%cheese%' 
AND   i.ING LIKE '%salmon%'

此时,问题应该清楚 - 有两种可能性,2种可能性超过1.

1)您的ING字段在单个字段中存储配方的所有成分。如果是这种情况,那么你就没有配方要求奶酪和鲑鱼。

2)您的ING字段每行只存储1种成分。但是,您要求的是包含CheeseSalmon的单行。这不是你的意图,因此查询是错误的。

-- SELECT ALL RECIPES USING CHEESE *OR* SALMON
SELECT r.recipeTitle AS recipe
FROM recipeIng il JOIN 
     Ingredient i ON  il.ingredientID = i.ingredientID JOIN
     Recipe r ON il.recipeID = r.recipeID
WHERE i.ING LIKE '%cheese%' 
AND   i.ING LIKE '%salmon%'

-- SELECT ALL RECIPES USING CHEESE *AND* SALMON
SELECT r.recipeTitle AS recipe
FROM recipeIng il JOIN 
     Ingredient iCheese 
         ON  il.ingredientID = i.ingredientID 
         AND i.ING LIKE '%cheese%'  JOIN
     Ingredient iSalmon 
         ON  il.ingredientID = i.ingredientID 
         AND i.ING LIKE '%salmon%'  JOIN 
     Recipe r ON il.recipeID = r.recipeID

请注意以上仅作为示例 - 在不知道您的架构的情况下,这些只是提示和建议:)

答案 2 :(得分:2)

使用i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%'代替AND,并使用GROUP BY r.recipeID添加HAVING COUNT(DISTINCT i.ING ) = 2,以确保所选的r.recipeID同时拥有ING

SELECT r.recipeTitle AS recipe
FROM Recipe r
WHERE recipeID IN(
    SELECT r.recipeID
    FROM recipeIng il
    INNER JOIN Ingredient i ON il.ingredientID = i.ingredientID 
    WHERE il.recipeID = r.recipeID
      AND (i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%')
    GROUP BY r.recipeID
    HAVING COUNT(DISTINCT i.ING ) = 2
);

SQL Fiddle Demo

因此,如果r.recipeID仅包含其中一个,那么COUNT(DISTINCT i.ING )将不会等于2,并且它将被淘汰。

HAVING COUNT(DISTINCT i.ING ) = 2将为您提供具有两个标签奶酪和鲑鱼的食谱,而不是更多成分,如果您正在寻找至少含有两种成分的食谱,请使用`HAVING COUNT(DISTINCT i.ING ) >= 2

这是假设成分在字段ING中输入为每行一个值。