LEFT JOIN会保留原始表中没有过滤条件的行。

14 浏览
0 Comments

LEFT JOIN会保留原始表中没有过滤条件的行。

以下查询对我来说很困惑。如果我在WHERE子句中使用了"WHERE (inventory_to_pos.POSID IS NULL OR inventory_to_pos.POSID = ?)"并绑定一个可能存在或不存在于inventory_to_pos表中的POSID,它没有显示products表中的所有行。当LEFT JOIN一个表时,当我仅在原始表上进行过滤并在LEFT JOIN的表中使用IS NULL进行任何条件时,我不应该获取到原始表的所有行吗?

在给定的产品和POSID的情况下,如果inventory_to_pos.PRODUCT和inventory_to_pos.POSID不存在,我将得到0行。为什么会这样?

0
0 Comments

在这段对话中,问题的原因是在WHERE子句中使用了过滤条件,而LEFT JOIN却没有过滤原始表格。这导致了结果集中缺少了一些行。解决方法是将所有与invetory_to_pos相关的子句移动到LEFT JOIN中。

原始的SQL查询如下:

SELECT
    products.ID,
    products. NAME,
    products.VOLUME,
    productcombinations.PRODUCTID,
    productcombinations.PART,
    inventory_to_pos.FULLCOUNT
FROM
    products
LEFT JOIN productcombinations ON products.ID = productcombinations.PARTOF
LEFT JOIN inventory_to_pos ON products.ID = inventory_to_pos.PRODUCT AND (
    inventory_to_pos.POSID IS NULL
    OR inventory_to_pos.POSID = ?
)
WHERE
    products.INVENTORY = 1
AND products.AVAILABLE = 1
AND products.ID > 0

根据对话中的讨论,MySQL首先根据WHERE语句过滤表格,然后再进行连接操作。在这种情况下,引擎首先会根据WHERE子句过滤inventory_to_pos表格,然后再进行JOIN操作,这与INNER JOIN是等价的。

但是根据WHERE子句,我希望只选择为NULL或具有特定值的行。我无法理解这与INNER JOIN相等,因为INNER JOIN要求两个表格中都有行。这让我完全困惑了。

对话中的解释是,如果你使用WHERE inventory_to_pos.POSID IS NULL而不是LEFT JOIN,引擎将只选择与该条件匹配的products表格的相应记录,以及products.ID = inventory_to_pos.PRODUCT。而使用LEFT JOIN,引擎首先选择所有的products行,然后将第二个表格JOIN并将其行与原始表格“粘合”在一起。希望你能理解这些解释的区别。

换句话说,INNER JOIN = (table1 + table2)然后再进行过滤,LEFT JOIN = (带有过滤条件的table1)+(带有过滤条件的table2)

你可以在这里查看更多解释:stackoverflow.com/questions/4752455,以及这里:stackoverflow.com/questions/15706112/…

如果我的回答解决了你的问题,请在话题中标记/勾选它以关闭问题。

0