我有一张 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。
关于mysql - LEFT JOIN 返回与 INNER JOIN 相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25954456/