【问题标题】:Why is WHERE condition ignored in LEFT JOIN?为什么在 LEFT JOIN 中忽略 WHERE 条件?
【发布时间】:2014-04-03 22:23:51
【问题描述】:

我在使用 WHERE 子句限制左侧结果集时遇到问题,即使我在形成右侧结果集的子查询中放置了相同的条件。这是一个例子:

SELECT shareItems.*, likes FROM shareItems LEFT JOIN
   (SELECT users_X_shareItems.itemID, COUNT(users_X_shareItems.userID) AS 'likes'
    FROM users_X_shareItems, shareItems WHERE shareItems.itemType = 2 AND
    users_X_shareItems.liked = 1
    GROUP BY users_X_shareItems.itemID) AS likeTable
ON shareItems.itemID = likeTable.itemID AND shareItems.itemType = 2

尽管我在两个查询中都指定了 shareItems.itemType = 2,但它被忽略了。有人知道为什么吗?谢谢。

【问题讨论】:

  • 请注意标题的细微变化 - 一个假设它 SQL 的错误/问题,而另一个提出问题并要求澄清。一个小问题,但尽量避免“乞求错误”。
  • 外部查询中没有 WHERE 子句。如果要在 WHERE 子句中应用谓词,则需要添加 WHERE 子句。顺便说一句...我认为您的人数被夸大了;在内联视图中,您正在对 item_id 执行 GROUP BY,但您正在加入 shareItems 表中itemType=2 的所有行;我们希望看到一个与itemIDshareItems.itemID 匹配的连接谓词。它只是看起来对我来说不见了;可能我不了解您的架构或您想要返回的结果集。
  • Spencer,您的观察是正确的,但这只是三向查询的一部分。完整的查询最终确实关联了 itemID。

标签: mysql sql left-join


【解决方案1】:

如果要限制 LEFT JOIN 的左侧,则需要将条件设置为 WHERE,而不是 JOIN(只会限制右侧):

 ON shareItems.itemID = likeTable.itemID
 WHERE shareItems.itemType = 2

【讨论】:

  • +1 没错。外部查询没有 WHERE 子句,外部查询没有“WHERE 条件”。在外连接的 ON 子句中计算的谓词不是 WHERE 子句中的谓词。
  • 太好了,谢谢!我曾尝试在顶部的初始 SELECT 中放置一个 WHERE 子句,但被拒绝了。所以我认为 ON 替换了 WHERE 并且可以包含附加条件。
【解决方案2】:

它们不会被忽略,它们是在来自连接内侧且在外部表中没有匹配的记录被添加到结果集中之前应用的。
因为谓词是连接的一部分,所以它作为连接的一部分应用,然后发生这种情况,所有来自内侧的没有匹配的记录都被添加回......由于没有匹配,外部的谓词边不能(根据 OUTRER 的定义 不能)然后应用。 所有这样的记录,因为在外部表中没有匹配,当然在任何应该来自该表的属性中都有空值,所以无论如何都不能应用谓词。

将谓词条件移动到 WHERE 子句中,然后它将在外连接之后应用,并执行您想要的操作。

【讨论】:

    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多