将 Join 与 Where 一起使用

Posted

技术标签:

【中文标题】将 Join 与 Where 一起使用【英文标题】:Using Join with Where 【发布时间】:2015-02-15 00:27:28 【问题描述】:

我有以下表格。

Table Name: Recipe
id  topic    description    difficultylevel     totaltime
1   Cheese   Cheese         Easy                10
2   Cheese1  Cheese1        Medium              50

Table Name: Ingredients
id  recipeid    ingredient
1   1           Butter
2   1           Cheese
3   1           Bread

现在,当我运行以下查询时,它会返回菜谱 id = "1",尽管它不应该返回,因为我不想要其中有黄油的菜谱。

SELECT recipe.id
FROM 
  `recipe`
  INNER JOIN ingredients ON recipe.id = ingredients.recipeid
WHERE 
  (recipe.description LIKE '%CHEESE%' OR recipe.topic LIKE '%CHEESE%')
  AND (recipe.difficultylevel='Easy')
  AND (recipe.totaltime <= 30)
  AND (ingredients.ingredient <> 'Butter')

由于 Cheese and Bread,它两次返回 recipe.id = "1"。我需要修复查询,以便它完全排除 recipe.id = "1" 如果它有黄油(例如)

【问题讨论】:

感谢@Michael 编辑问题。看起来更容易阅读。我真的不知道该怎么做。 select distinct?至于格式化您的代码,只需在编辑器中突出显示它并点击 按钮。 使用突出显示代码上的 编辑器工具栏按钮或ctl-k 格式化代码块。 感谢有关如何格式化的帮助。 SELECT DISTINCT 将不起作用,因为它仍然会返回一次 recipe.id = "1" 它根本不应该 您得到 1 的回报,因为当成分是奶酪或面包时,您的 where 子句为真。您需要一种不同的方法。 【参考方案1】:

如果我理解您的问题,我认为您不需要inner join。您可以使用outer joinnull 检查,也可以使用not exists

select id
from recipe r
where 
    (recipe.description LIKE '%CHEESE%' OR recipe.topic LIKE '%CHEESE%')
    AND (recipe.difficultylevel='Easy')
    AND (recipe.totaltime <= 30)
    AND not exists (
        select 1
        from ingredients i
        where r.id = i.recipeid
             and i.ingredient = 'Butter'
    )

【讨论】:

谢谢你不知道'NOT EXISTS'和'EXISTS'方法。【参考方案2】:

为确保包含Butter 的配方不在输出中,您可以使用包含= 'Butter' 条件的LEFT JOIN。在主查询的WHERE 子句中,您需要在ingredients 的列上查找IS NULL,以确保您获得 匹配项。

SELECT recipe.id
FROM
  recipe
  -- Join condition specifically looks for 'Butter' (other ingredients may be chained with OR inside () )
  LEFT JOIN ingredients ON recipe.id = ingredients.recipe_id AND (ingredient = 'Butter')
WHERE
  (recipe.description LIKE '%CHEESE%' OR recipe.topic LIKE '%CHEESE%')
  AND (recipe.difficultylevel='Easy')
  AND (recipe.totaltime <= 30)
  -- NULL condition for matching ingredient
  AND (ingredients.ingredient IS NULL)

这是一个演示,返回 1 个符合您的条件的食谱:http://sqlfiddle.com/#!2/73f975/1

【讨论】:

你击败了我的反加入答案...为你+1! 该解决方案效果很好,但如果我想要一个没有“黄油1”但有“奶酪”的食谱。它应该返回 1 但它没有。 sqlfiddle.com/#!2/f6c5c0/4/0 @SaadBashir 修改 Michael 提供的查询以满足您的需求并不难。他已经充分回答了您的问题,现在由您自己解决问题。 @MichaelBerkowski 非常感谢您的帮助。真的很感激

以上是关于将 Join 与 Where 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

与来自 JOIN 的 WHERE 一起加入 [重复]

使用 wpdb prepare 安全地收集带有“join”的“where”子句数组

将 SELECT DISTINCT ON 与 OrmLite 一起使用

最全解释Mysql 的join中on与where 过滤条件差异

将 join 与 delete 语句一起使用时出现语法错误 [重复]

使用 JOIN 时的 WHERE 子句与 ON