mysql - LEFT JOIN 返回与 INNER JOIN 相同的结果

标签 mysql sql join left-join

我有一张 table (磨砂膏),上面有 1600 件不同的元素。第二张 table 有 100 万以上。我运行我的 INNER JOIN 并获得 65 个匹配项:

SELECT a.`BW Parent Number` , a.`Vendor Name`, b.`Parent Supplier Name` 
FROM `scrubs` AS a
JOIN pdwspend AS b ON a.`BW Parent Number` = b.`Child Supplier ID`
WHERE a.`year` =2014
AND b.`BU ID` = 'BU_1'
AND b.version LIKE '%GOV%'
GROUP BY a.`BW Parent Number` 

然后我运行 LEFT OUTER JOIN 并得到相同的 65 个结果:

SELECT a.`BW Parent Number` , a.`Vendor Name`, b.`Parent Supplier Name`  
FROM `scrubs` AS a
LEFT OUTER JOIN pdwspend AS b ON a.`BW Parent Number` = b.`Child Supplier ID` 
WHERE a.`year` =2014
AND b.`BU ID` = 'BU_1'
AND b.version LIKE '%GOV%'
GROUP BY a.`BW Parent Number`

为什么不从左表中取出所有行,并为 b.Parent Supplier Name 下不匹配的行显示 NULL?

谢谢!

最佳答案

为什么不从左表中提取所有行并为不匹配的行显示 NULL?

LEFT JOIN 没有按预期工作的原因是 WHERE 子句中该表的条件;这有时称为“隐式内部连接”。

这最好通过演示来解释。下面是2个简单的表格

    | USER_ID | FIRST_NAME |  LAST_NAME |
    |---------|------------|------------|
    |     123 |       Fred | Flintstone |
    |     456 |     Barney |     Rubble |

    |    ID | USER_ID |       NOTE_BODY |
    |-------|---------|-----------------|
    | 98765 |     123 | Yabba Dabba Doo |

因此,如您所料,INNER JOIN 仅生成一行,其中 User_ID 值在两个表中都匹配。

SELECT * FROM users u INNER JOIN user_notes n ON u.User_ID = n.User_ID;

    | USER_ID | FIRST_NAME |  LAST_NAME |    ID |       NOTE_BODY |
    |---------|------------|------------|-------|-----------------|
    |     123 |       Fred | Flintstone | 98765 | Yabba Dabba Doo |

通过更改为 LEFT JOIN,我们获得了 Users 中的所有记录,但并非所有记录都来自 User_Notes,因此我们在这些列中获得了 NULL

SELECT * FROM users u LEFT JOIN user_notes n ON u.User_ID = n.User_ID;

    | USER_ID | FIRST_NAME |  LAST_NAME |     ID |       NOTE_BODY |
    |---------|------------|------------|--------|-----------------|
    |     123 |       Fred | Flintstone |  98765 | Yabba Dabba Doo |
    |     456 |     Barney |     Rubble | (null) |          (null) |

但是如果我们真的只想要连接表中的一些记录会怎样呢?

SELECT * FROM users u LEFT JOIN user_notes n ON u.User_ID = n.User_ID WHERE n.Note_Body = 'Yabba Dabba Doo';

    | USER_ID | FIRST_NAME |  LAST_NAME |    ID |       NOTE_BODY |
    |---------|------------|------------|-------|-----------------|
    |     123 |       Fred | Flintstone | 98765 | Yabba Dabba Doo |

好吧,如果我们使用 WHERE 条件,效果与 INNER JOIN 相同,现在我们不会获取所有用户记录,这是一个隐式内部联接

我们没有获得所有用户记录的原因是因为我们现在坚持所有结果行必须在可能为 NULL 的列中具有特定值。因此,我们可以更改 WHERE 条件以允许 NULL。

SELECT * FROM users u LEFT JOIN user_notes n ON u.User_ID = n.User_ID WHERE ( n.Note_Body = 'Yabba Dabba Doo' OR n.Note_Body IS NULL);

    | USER_ID | FIRST_NAME |  LAST_NAME |     ID |       NOTE_BODY |
    |---------|------------|------------|--------|-----------------|
    |     123 |       Fred | Flintstone |  98765 | Yabba Dabba Doo |
    |     456 |     Barney |     Rubble | (null) |          (null) |

我们添加了连接条件(即在 ON 之后),而不是在连接表上使用 WHERE 子句

SELECT * FROM users u LEFT JOIN user_notes n ON u.User_ID = n.User_ID AND n.Note_Body = 'Yabba Dabba Doo';

    | USER_ID | FIRST_NAME |  LAST_NAME |     ID |       NOTE_BODY |
    |---------|------------|------------|--------|-----------------|
    |     123 |       Fred | Flintstone |  98765 | Yabba Dabba Doo |
    |     456 |     Barney |     Rubble | (null) |          (null) |

因此,在使用外连接时要小心,您的 where 子句不会覆盖外连接允许的 NULL。

See the above as a SQLFiddle demonstration

关于mysql - LEFT JOIN 返回与 INNER JOIN 相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25954456/

相关文章:

mysql - 如何获得行排名?

带有预选值的 PHP 下拉列表

SQL 查询在 Excel 中不起作用,但在 Access 中起作用

sql - 在静态项目列表上左加入?

MYSQL从多个表中进行多重选择

php - Yii2 viaTable 连接条件

php - 我需要有关我的网站上已安装的自动检测语言的帮助

php - "No database selected"即使明确选择了 db

mysql - 从表中选择一个值并保留它

mysql - SQL 用于查找一个值,该值的行最接近另一个值的所有唯一出现次数的一半?