You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL WHERE不等于条件失效:查询不含指定食材的菜谱失败

解决多对多关系中查询不包含特定食材的菜谱问题

嗨,我来帮你捋清楚这个问题!你当前的查询之所以会返回所有菜谱,核心原因是:当一个菜谱包含多种食材时,只要其中有一个食材ID不是307,这条关联记录就会被保留下来,最后GROUP BY之后还是会把这个菜谱纳入结果——哪怕它其实包含了ID为307的食材。

举个例子:假设某个菜谱同时有食材307和308,你的查询会过滤掉食材307的那条关联记录,但食材308的记录还在,GROUP BY之后这个菜谱依然会出现在结果里,这显然不是你想要的。

下面给你几种靠谱的解决方案:

方案1:使用NOT EXISTS(推荐,性能友好)

这种方式直接检查菜谱是否不存在关联的目标食材,逻辑清晰,数据库也能高效利用索引:

SELECT * 
FROM recipes r
WHERE NOT EXISTS (
    SELECT 1 
    FROM recipe_ingredients ri
    WHERE ri.fk_Recipe = r.id 
      AND ri.fk_Ingredient = 307
);

方案2:使用LEFT JOIN + IS NULL

通过左连接关联目标食材的记录,然后筛选出没有匹配到的菜谱:

SELECT r.* 
FROM recipes r
LEFT JOIN recipe_ingredients ri 
    ON r.id = ri.fk_Recipe 
    AND ri.fk_Ingredient = 307
WHERE ri.fk_Recipe IS NULL;

这里的关键是把ri.fk_Ingredient = 307写在JOIN条件里,而不是WHERE里,这样才能保留所有菜谱,再过滤掉有匹配的记录。

方案3:使用GROUP BY + HAVING统计

通过分组统计每个菜谱包含目标食材的次数,筛选出次数为0的菜谱:

SELECT r.* 
FROM recipes r
JOIN recipe_ingredients ri ON r.id = ri.fk_Recipe
GROUP BY r.id, r.url -- 注意:需要包含recipes表所有非聚合字段,具体取决于你的SQL模式
HAVING SUM(CASE WHEN ri.fk_Ingredient = 307 THEN 1 ELSE 0 END) = 0;

这三种方法都能精准筛选出完全不包含ID为307的食材的菜谱,你可以根据自己的数据库环境选择最顺手的一种~

内容的提问来源于stack exchange,提问作者AirwaveQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:48:46