如何根据一组整数(ID)仅返回满足所有条件的行?

时间:2014-01-02 17:20:06

标签: mysql

从页面 - MyBarCabinet - 我可以选择我可用的原材料。这些原材料(仅ID)放入一个数组并存储在cookie中。

现在;我的目标是只获得不需要更多/其他原料的饮料,而不是存储在饼干中的饮料。换一种说法;如果我检查过我只有“16”,“34”和“35”可用:只有那些只需要这些原料的饮料才会出现,而不是其他原料中含有这些原料的饮料。

我从MySQL数据库查询饮料和所有这些。这部分由三个表组成:drinks_recipesdrink_recipes_ingredientsraw_materials drink_recipes_ingredients - 表用于将饮料配方与原料“链接”。

如果我这样做:

SELECT 
    dr.id drink_id, dr.name drink_name,
    rm.name ingredient_name
FROM drink_recipes_ingredients dri
    JOIN drink_recipes dr ON dr.id = dri.fk_recipes_id
    JOIN raw_materials rm ON rm.id = dri.fk_raw_materials_id
WHERE rm.id IN (16,34,35)

这正是我不想要的。我得到的所有饮料中都含有至少一种选定的原料。

我确实看过这篇文章:How to return a row only if multiple clauses are met,但在我的案例中我无法弄清楚如何做类似的事情。但目标看起来是一样的。

3 个答案:

答案 0 :(得分:2)

Baramar似乎有一个有趣的解决方案,但对于这种问题,我通常使用“找到相反的”方法。我们首先找到与您的清单不符的所有饮料。然后我们选择那些不是那些的饮料:

SELECT *
FROM drink_recipes
WHERE drink_recipes.id NOT IN (    
    SELECT 
        dr.id 
    FROM drink_recipes_ingredients dri
        JOIN drink_recipes dr ON dr.id = dri.fk_recipes_id
        JOIN raw_materials rm ON rm.id = dri.fk_raw_materials_id
    WHERE rm.id NOT IN (16,34,35)
)

答案 1 :(得分:1)

不是返回与成分匹配的行,而是计算匹配的所选成分的数量。然后你可以将它与成分总数进行比较,看看是否还有其他成分。

SELECT 
    dr.id drink_id, dr.name drink_name,
    rm.name ingredient_name,
    SUM(rm.id IN (16, 34, 35)) AS matched_count,
    COUNT(*) AS all_count
FROM drink_recipes_ingredients dri
    JOIN drink_recipes dr ON dr.id = dri.fk_recipes_id
    JOIN raw_materials rm ON rm.id = dri.fk_raw_materials_id
GROUP BY dr.id
HAVING matched_count > 0 AND matched_count = all_count

答案 2 :(得分:0)

我有其他解决方案......从数学的角度来看,也许并不那么优雅。

SELECT 
      dr.id drink_id
    , dr.name drink_name
    , rm.name ingredient_name
FROM 
    drink_recipes_ingredients dri
    JOIN drink_recipes dr ON dr.id = dri.fk_recipes_id
    JOIN raw_materials rm ON rm.id = dri.fk_raw_materials_id
GROUP BY dr.id, dr.name, rm.name
WHERE GROUP_CONCAT(rm.id ORDER BY rm.id SEPARATOR '|') = '16|34|35'

字符串'16|34|35'是来自cookie的连接ID。您可以在应用程序代码中进行准备。

相关问题