为什么不把左表的所有行都带进来,不匹配的行显示为 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,我们获得了用户中的所有记录,但并非所有记录都具有来自 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 为空);
| 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