简体   繁体   English

WHERE子句中的多行条件

[英]Multiple row conditions in WHERE clause

I am having trouble writing the following query in MySQL. 我无法在MySQL中编写以下查询。 I have a table called pizz0r_pizza_ingredients which looks something like this: 我有一个名为pizz0r_pizza_ingredients的表,看起来像这样:

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

I want to search for pizzas where the ingredients have specific requirements such as the following: 我想搜索原料具有特定要求的比萨饼,例如:

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

I am trying to get entries where ingredient is equal to 15, but ignores that pizza_id if it also has ingredient 20. 我正在尝试获取ingredient等于15的条目,但是如果它也具有成分20,则忽略了pizza_id。

The current result is 1 , but in this example nothing should be returned. 当前结果为1 ,但在此示例中,不返回任何内容。

Try this: 尝试这个:

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;

I like to handle these problems using group by and having : 我喜欢用处理这些问题group byhaving

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

You can add as many new requirements as you like. 您可以根据需要添加任意数量的新需求。 The SUM() expression counts the number of ingredients of a certain type. SUM()表达式计算某种类型的成分的数量。 The > 0 means that there is at least one on the pizza. > 0表示披萨上至少有一个。 The = 0 means that there are none. = 0表示不存在。

You need to combine the two sets of data - everything you might want, and then exclude those that intersect your unwanted ingredients, so something like: 您需要结合两组数据-可能需要的所有数据,然后排除与不需要的成分相交的数据,例如:

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

EDIT: Your question was unclear earlier. 编辑:您的问题尚不清楚。 If you wanted to exclude pizzas with ingredient 20, you can use the below: 如果要排除成分为20的比萨饼,可以使用以下方法:

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

NOTE: EXCEPT is generally faster than join or not in 注意: EXCEPT通常比joinnot in join速度快

One option you have is to use subqueries for this. 您必须选择的一种方法是使用子查询。 To understand this best, I would first separate the two queries and then combine them. 为了更好地理解这一点,我首先将两个查询分开,然后将它们组合在一起。

The first one will pull all pizza_id that have ingredient 15: 第一个将提取所有具有成分15的pizza_id

SELECT DISTINCT pizza_id
FROM myTable
WHERE ingredient = 15;

Then, you can write another one that searches for pizza_id where ingredient is equal to 20: 然后,您可以编写另一个搜索披萨ID等于20的披萨ID:

SELECT DISTINCT pizza_id
FROM myTable
WHERE ingredient = 20;

Last, you can combine the two by using the NOT IN clause. 最后,您可以使用NOT IN子句将两者结合起来。 In other words, you can select all pizza_id that meet the first condition, where the id is NOT IN the pizza_ids that meet the second condition: 换句话说,您可以选择所有符合第一个条件的pizza_id,其中id不在符合第二个条件的pizza_id中:

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

EDIT 编辑

Here is an SQL Fiddle . 这是一个SQL Fiddle

EDIT 2 编辑2

This is a subject known as relational division. 这是称为关系划分的主题。 There is another example similar to this here . 有类似于此另一个例子在这里

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

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