在MySQL中使用来自另一个表的多个标准来计算不同的记录

时间:2010-11-19 04:20:44

标签: sql mysql relational-database

这不是家庭作业。我更改了表和字段的名称,仅用于说明目的。我承认我是MySQL的新手。请在答案中考虑这一点。

说明我需要的查询功能的最好方法是这样:

我有两张桌子。

一个表与另一个表的关系为0..1到0..n。

对于Simplicities Sake Only,假设这两个表是Recipe and Ingredient。

Ingredient表中的一个字段引用Recipe表,但可以为null。

仅举例: alt text

我想知道SQL之类的东西:有多少食谱要求“橄榄”的数量为“1”,“蘑菇”的数量为“2”

作为结构化查询语言的新手,我甚至不确定该如何获取此信息。

我是否在以下方面走上正轨?:

SELECT COUNT(DISTINCT Recipe.ID) AS Answer FROM Recipe, Ingredient 
  WHERE Ingredient.RecipeID=Recipe.ID AND Ingredient.Name='Olives'
  AND Ingredient.Amount=1 AND Ingredient.Name='Mushrooms'
  AND Ingredient.Amount=2

我意识到这是完全错误的,因为名字不能同时是橄榄和蘑菇......但是不知道要放什么,因为我需要用两者来计算所有食谱,但只考虑两者的所有食谱。

如何正确地为MySQL编写这样的查询?

5 个答案:

答案 0 :(得分:3)

你很亲密。

尝试类似

的内容
SELECT  COUNT(Recipe.ID) Answer
FROM    Recipe INNER JOIN
        Ingredient olives ON olives.RecipeID=Recipe.ID INNER JOIN
        Ingredient mushrooms ON mushrooms.RecipeID=Recipe.ID 
WHERE   olives.Name='Olives'
AND     mushrooms.Name='Mushrooms'
AND     olives.Amount = 1
AND     mushrooms.Amount = 2

你可以两次加入同一张桌子,你需要做的只是给表格一个合适的alias

答案 1 :(得分:3)

使用:

SELECT COUNT(r.id)
  FROM RECIPE r
 WHERE EXISTS(SELECT NULL
                FROM INGREDIENTS i
               WHERE i.recipeid = r.id
                 AND i.name = 'Olives'
                 AND i.amount = 1)
   AND EXISTS(SELECT NULL
                FROM INGREDIENTS i
               WHERE i.recipeid = r.id
                 AND i.name = 'Mushrooms'
                 AND i.amount = 2)

答案 2 :(得分:1)

SELECT COUNT(DISTINCT Recipe.ID) AS Answer 
FROM Recipe, Ingredient as ing1, Ingredient as ing2
WHERE 
  Ing1.RecipeID=Recipe.ID AND Ing1.Name="Olives" AND ing1.Amount=1 AND 
  Ing2.RecipeID=Recipe.ID AND Ing2.Name="Mushrooms" AND ing2.Amount=2;

希望这个帮助

答案 3 :(得分:0)

首先,您使用旧的连接语法。 INNER JOIN创建相同的执行计划,但更清晰。然后,您的查询是关于一个简单的旧条件。你只需要正确地写它们! (这需要一些练习,我同意。)

SELECT COUNT(DISTINCT R.ID) Answer
FROM Recipe R
INNER JOIN Ingredient I
    ON R.ID = I.RecipeID
    AND (R.Name = 'Olives' AND I.Amount = 1)
    OR (R.Name = 'Mushrooms' AND I.Amount = 2);

以下是我的示例数据:

mysql> SELECT * FROM Ingredient;
+------+------+--------+----------+
| ID   | Name | Amount | RecipeID |
+------+------+--------+----------+
|    1 | I1   |      1 |        1 |
|    1 | I2   |      2 |        1 |
|    1 | I3   |      2 |        1 |
|    1 | I4   |      3 |        1 |
|    1 | I1   |      1 |        2 |
|    1 | I2   |      1 |        2 |
|    1 | I3   |      3 |        2 |
|    1 | I4   |      2 |        2 |
|    1 | I1   |      2 |        3 |
|    1 | I2   |      1 |        3 |
+------+------+--------+----------+
10 rows in set (0.00 sec)

mysql> SELECT * FROM Recipe;
+------+-----------+
| ID   | Name      |
+------+-----------+
|    1 | Mushrooms |
|    2 | Olives    |
|    3 | Tomatoes  |
+------+-----------+
3 rows in set (0.00 sec)

我的查询输出2,应该如此。

编辑:实际上,我意识到我的查询选择了错误的行。这可以正常工作:

SELECT COUNT(DISTINCT R.Id) Answer 
FROM Recipe R 
INNER JOIN Ingredient I 
    ON R.ID = I.RecipeID 
WHERE 
    (R.Name = 'Mushrooms' AND I.Amount = 2) 
    OR (R.Name = 'Olives' AND I.Amount = 1);

哪个输出也是。

答案 4 :(得分:0)

仅供参考......

有多少食谱要求“橄榄”的数量为“1”,“蘑菇”的数量为“2”

查看上面的表格结构,您可能希望 associative entity 介于配方和配料之间。通过 inner join ,您可以轻松完成所需的查询。

在你的两张桌子之间,我会想象这样的事情......

Recipe_Ingredient
-----------------
(PK, FK) RecipeID
(PK, FK) IngredientID

如果你有,那么每个食谱可能含有许多成分,每种成分可能是许多食谱的一部分。一旦你有了这样的表来正确地关联你的两个表,你可以将它们连接在一起并得到一个完整的配方。对于像这样的更复杂的查询,你有两个食谱的单独条件,我可能会对它进行子查询以帮助理解。

SELECT SUM(RecipeCount) as RecipeCount
FROM
(
    SELECT COUNT(r.*) as RecipeCount
    FROM Recipe r
    INNER JOIN Recipe_Ingredient ri on r.ID = ri.RecipeID
    INNER JOIN Ingredient i on i.ID = ri.IngredientID
    WHERE i.Name = 'Olives' AND i.Amount = 1
UNION ALL
    SELECT COUNT(r.*) as RecipeCount
    FROM Recipe r
    INNER JOIN Recipe_Ingredient ri on r.ID = ri.RecipeID
    INNER JOIN Ingredient i on i.ID = ri.IngredientID
    WHERE i.Name = 'Mushrooms' AND i.Amount = 2
) as subTable