简体   繁体   English

MySQL“ AND”查询未按预期工作

[英]MySQL 'AND' query not working as expected

I've got 3 tables i'm currently working on. 我目前正在处理3张桌子。 Recipe, Ingredient and recipeIng. 食谱,配料和食谱 It's the classic many to many situation, with recipeIng there to solve that problem. 这是经典的“多对多”情况,那里有诀窍可以解决该问题。

However, i'm having trouble getting a what I assumed to be, a fairly simple 'AND' query. 但是,我很难获得一个我想是的东西,一个相当简单的“ AND”查询。 What i'm trying to achieve is searching for multiple ingredients at once. 我想要实现的是一次搜索多种成分。 For instance: 例如:

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%')

);

While the query runs, it outputs nothing. 查询运行时,不输出任何内容。 I can't seem to see what i'm doing wrong here. 我似乎看不到我在做什么错。 Any help would be really appreciated. 任何帮助将非常感激。

Thanks. 谢谢。

So basically you want the recipes that includes any of the ingredients you're querying on. 因此,基本上,您需要包含要查询的任何成分的食谱。 This can be performed using simple straight joins: 可以使用简单的直接联接来执行:

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%'

The DISTINCT() makes sure that you're not seeing the same recipe twice in case it contains both ingredients. 如果DISTINCT()包含两种成分,则确保您不会两次看到相同的食谱。

If both ingredients must be present in the recipes, you must use AND instead of OR . 如果配方中必须同时存在两种成分,则必须使用 AND代替 OR

First of all, your query can be massively simplified as you do not need the outer query. 首先,由于不需要外部查询,因此可以大大简化查询。 The following is exactly the same: 以下内容完全相同:

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%')

Secondly, you don't need all those brackets. 其次,您不需要所有这些括号。

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%'

Thirdly, you should INNER JOIN your tables to make the relationship between them clearer: 第三,您应该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%'

At this point, the issue should be clear - there are 2 likely possibilities, and 2 is more likely than 1. 此时,问题应该很清楚-有2种可能的可能性,而2种可能性大于1种。

1) Your ING field stores all the ingredients for a recipe in a single field. 1)您的ING字段将配方的所有成分存储在一个字段中。 If this is the case then you do not have a recipe who's ingredients call for both Cheese and Salmon. 如果是这种情况,那么您没有食谱要求同时使用奶酪和鲑鱼的食谱。

2) Your ING field only stores 1 ingredient per row. 2)您的ING字段每行仅存储1种成分。 However, you are asking for a single row which contains both Cheese and Salmon . 但是,您要的是一行同时包含CheeseSalmon This is not your intention, and the query is therefore wrong. 这不是您的意图,因此查询是错误的。

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

Please note the above are for example only - without knowing your schema, these are merely hints and suggestions :) 请注意,以上仅作为示例-在不了解您的架构的情况下,这些仅仅是提示和建议:)

Use i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%' instead of AND , and add GROUP BY r.recipeID with HAVING COUNT(DISTINCT i.ING ) = 2 to ensure that the selected r.recipeID have both ING : 使用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 SQL小提琴演示

So if the r.recipeID have only one of them only, then the COUNT(DISTINCT i.ING ) won't be equal to 2 and there for it will be eliminated. 因此,如果r.recipeID仅具有其中一个,则COUNT(DISTINCT i.ING )将不等于2,并且在那里将被消除。

The HAVING COUNT(DISTINCT i.ING ) = 2 will give you those recipes that has exactly the two tags cheese and salmon only no more ingredients, if you are looking for those recipes that has at least both two ingredients, use `HAVING COUNT(DISTINCT i.ING ) >= 2 . HAVING COUNT(DISTINCT i.ING ) = 2将为您提供仅具有两个标签奶酪和三文鱼的食谱,如果您要查找包含至少两种成分的食谱,请使用`HAVING COUNT(DISTINCT i.ING ) >= 2

This is assuming that ingredients are entered in the field ING as a one value per row. 假定成分以每行一个值的形式输入到ING字段中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM