具有复杂条件的多对多选择

时间:2014-05-24 11:32:29

标签: sql select many-to-many

我有桌子:

+------------+
| Ingredient |
+------------+
| id         |
+------------+
| name       |
+------------+

+---------------+
| Relingredient |
+---------------+
| id_ingredient |
+---------------+
| id_recipe     |
+---------------+

+--------+
| Recipe |
+--------+
| id     |
+--------+
| name   |
+--------+

并且我需要选择具有我想要的成分的食谱(所有成分传递给他们)我试过这个:

SELECT R.id, R.nom FROM Recipe R, Relingredient RI, Ingredient I 
WHERE  R.id = RI.id_recipe AND RI.id_ingredient = I.id AND I.name='onion' AND I.name='oil' 
GROUP BY R.name

但重新调整零行

我也试过这个:

SELECT R.id, R.nom FROM Recipe R, Relingredient RI, Ingredient I 
WHERE  R.id = RI.id_recipe AND RI.id_ingredient = I.id AND (I.name='onion' or I.name='oil') 
GROUP BY R.name

但它会选择所有含有洋葱或油的食谱,而不仅仅是那些含有洋葱 AND 油的食谱......我该怎么办?

(编辑)我想要的样本:
例如我有食谱:
1:烤鸡(配料:鸡肉,洋葱,油)
2:中国汤(配料:猪肉,洋葱,油,面条)
3:蔬菜三明治(配料:面包,油,番茄,沙拉)
查询应该只返回食谱:烤鸡肉和中国汤

谢谢你的帮助!!

3 个答案:

答案 0 :(得分:1)

尝试这样的事情:

SELECT
  R.id, R.name
FROM Recipt R
  JOIN Relingredient RI
    ON R.Id = RI.Id_recipe
  JOIN Ingredient I
    ON RI.Id_ingredient = I.Id
WHERE I.name = 'onion'
    OR I.name='oil'
GROUP BY R.id, R.name
HAVING COUNT(I.name) = 2

答案 1 :(得分:0)

试试这个:

SELECT R.id, R.name FROM Recipe R
       Where R.Id in (
                         Select RI.Id_recipe From Relingredient as RI 
                                INNER JOIN Ingredient as I ON  RI.Id_ingredient = I.Id
                                WHERE I.name = 'onion'
                                      OR I.name='oil'
                     )

我完全明白了。 新查询:

SELECT  *
        FROM    dbo.Recipt
        WHERE   Id IN ( SELECT  id_recipe
            FROM    dbo.Relingredient
                    INNER JOIN dbo.Ingredient ON id_ingredient = Id
            WHERE   Name = 'oil' )
    AND Id IN ( SELECT  id_recipe
                FROM    dbo.Relingredient
                        INNER JOIN dbo.Ingredient ON id_ingredient = Id
                WHERE   Name = 'union' )

答案 2 :(得分:0)

要获得您正在寻找的成分,请使用having条款:

SELECT R.id, R.nom
FROM Recipe R JOIN
     Relingredient RI
     ON R.id = RI.id_recipe JOIN
     Ingredient I 
     ON RI.id_ingredient = I.id
GROUP BY R.name
HAVING SUM(CASE WHEN I.name = 'onion' THEN 1 ELSE 0 END) > 0 AND
       SUM(CASE WHEN I.name = 'oil' THEN 1 ELSE 0 END) > 0 AND
       SUM(CASE WHEN I.name NOT IN ('onion', 'oil') THEN 1 ELSE 0 END) = 0;

having子句中的每个条件都会检查其中一个条件。首先检查至少一种成分是“洋葱”,第二种是至少一种是“油”,第三种是没有其他成分存在。如果你想允许其他成分,请删除最后一个条款。

这种方法对于成分的不同条件非常灵活。

编辑:

以下having子句允许您仅为配料命名一次。但您还需要插入计数:

HAVING COUNT(DISTINCT CASE WHEN I.name IN ('onion', 'oil') THEN I.name END) = COUNT(DISTINCT NAME) AND
       COUNT(DISTINCT NAME) = 2;

如果一个食谱不止一次包含一种成分,distinct就会出现。