WHERE子句中的多行条件

时间:2014-12-29 14:10:09

标签: mysql sql join group-by relational-division

我在MySQL中编写以下查询时遇到问题。我有一个名为pizz0r_pizza_ingredients的表,看起来像这样:

| id | pizza_id | ingredient | amount | measure |
+----+----------+------------+--------+---------+
| 6  |    1     |    15      |   3    |    4    |
|178 |    17    |    1       |   160  |    1    |
| 3  |    1     |    20      |   3    |    4    |

我想搜索成分具有特定要求的比萨饼,如下所示:

SELECT `pizza_id` 
FROM `pizz0r_pizza_ingredients` 
WHERE `ingredient` = 15 AND `ingredient` != 20 
GROUP BY `pizza_id`

我正在尝试获取ingredient等于15的条目,但如果它还包含成分20,则忽略该pizza_id。

当前结果为1,但在此示例中不应返回任何内容。

5 个答案:

答案 0 :(得分:2)

试试这个:

SELECT P1.pizza_id 
FROM pizz0r_pizza_ingredients P1 
LEFT OUTER JOIN pizz0r_pizza_ingredients P2 ON P1.pizza_id = P2.pizza_id AND P2.ingredient IN (20, 21)
WHERE P1.ingredient = 15 AND P2.id IS NULL
GROUP bY P1.pizza_id;

答案 1 :(得分:2)

我喜欢使用group byhaving处理这些问题:

SELECT `pizza_id` 
FROM `pizz0r_pizza_ingredients` 
GROUP BY `pizza_id`
HAVING SUM(ingredient = 15) > 0 AND
       SUM(ingredient = 20) = 0;

您可以根据需要添加任意数量的新要求。 SUM()表达式计算某种类型的成分数。 > 0表示披萨上至少有一个。 = 0表示没有。

答案 2 :(得分:0)

您需要将两组数据组合在一起 - 您可能需要的所有数据,然后排除那些与您不需要的成分相交的数据,例如:

SELECT DISTINCT
            wanted.pizza_id

FROM        pizz0r_pizza_ingredients wanted 

LEFT JOIN   pizz0r_pizza_ingredients dontwant
    ON      wanted.pizza_id = dontwant.pizza_id
    AND     dontwant.ingredient IN ( 20, 21 )

WHERE       wanted.ingredient IN ( 15 ) -- You could have multiples, if you wanted ham OR chicken, for example
    AND     dontwant.pizza_id IS NULL -- No bad ingredients

答案 3 :(得分:0)

编辑:您之前的问题尚不清楚。如果你想用成分20排除比萨饼,可以使用下面的代码:

select pizzaid from pizz0r_pizza_ingredients where ingredient = 15
EXCEPT
select pizzaid from pizz0r_pizza_ingredients where ingredient != 20

注意: EXCEPT通常比joinnot in

更快

答案 4 :(得分:0)

您拥有的一个选项是使用子查询。为了最好地理解这一点,我首先将两个查询分开,然后将它们组合起来。

第一个将拉出具有成分15的所有pizza_id

SELECT DISTINCT pizza_id
FROM myTable
WHERE ingredient = 15;

然后,你可以写另一个搜索pizza_id,其中的成分等于20:

SELECT DISTINCT pizza_id
FROM myTable
WHERE ingredient = 20;

最后,您可以使用NOT IN子句将两者结合起来。换句话说,您可以选择满足第一个条件的所有pizza_id,其中id不在满足第二个条件的pizza_ids中:

SELECT DISTINCT pizza_id
FROM myTable
WHERE ingredient = 15 AND pizza_id NOT IN(
  SELECT DISTINCT pizza_id
  FROM myTable
  WHERE ingredient = 20);

修改

这是SQL Fiddle

编辑2

这是一个称为关系分裂的主题。还有另一个类似于here的例子。