SQL LEFT JOIN,附加条件已添加到ON

时间:2019-01-21 08:34:55

标签: sql oracle oracle11g

table: users
+----+-------+
| id | name  |
+----+-------+
|  1 | alpha |
|  2 | beta  |
|  3 | gamma |
+----+-------+

table: address
+----+---------+------+--------------+
| id | user_id | type |   address    |
+----+---------+------+--------------+
|  1 |       1 | PRA  | welcome      |
|  2 |       1 | COA  | to the hotel |
|  3 |       2 | PRA  | california   |
+----+---------+------+--------------+

我了解此查询的结果:

select u.*, a.*
from ccr.SJ_TEMP_USERS u
LEFT JOIN SJ_TEMP_ADDRESS a
on u.id = a.USER_ID
WHERE a.id IS NULL;
+----+-------+--------+---------+--------+---------+
| ID | NAME  |  ID_1  | USER_ID |  TYPE  | ADDRESS |
+----+-------+--------+---------+--------+---------+
|  3 | gamma | (null) | (null)  | (null) | (null)  |
+----+-------+--------+---------+--------+---------+

但是我不理解该查询的结果。

select u.*, a.*
from ccr.SJ_TEMP_USERS u
LEFT JOIN SJ_TEMP_ADDRESS a
on u.id = a.USER_ID
and a.type = 'COA'
WHERE a.id IS NULL;

+----+-------+--------+---------+--------+---------+
| ID | NAME  |  ID_1  | USER_ID |  TYPE  | ADDRESS |
+----+-------+--------+---------+--------+---------+
|  3 | gamma | (null) | (null)  | (null) | (null)  |
|  2 | beta  | (null) | (null)  | (null) | (null)  |
+----+-------+--------+---------+--------+---------+

请帮助我理解为什么我在第二个查询中得到带有“ beta”的行。 (我正在使用Oracle SQL Developer)。

请注意,如果我输入条件a.type = 'PRA'而不是a.type = 'COA',则不会显示带有'alpha'的行

2 个答案:

答案 0 :(得分:2)

where子句在连接之后发生。 on子句将应用于联接本身,因此在a.type = 'COA'子句中额外添加的on将排除更多地址,同时不影响users表的结果(直到您开始使用where子句进行过滤)。

更具体地说:

在第一个查询中,您说“给我所有没有匹配地址的行”。这仅适用于Gamma,因为没有地址为user_id 3的地址。

在第二个查询中,您说“给我所有没有匹配类型为“ COA”的地址的行,这对于Gamma和Beta是正确的,因为Beta的地址是另一种类型。 / p>

答案 1 :(得分:1)

您要尝试的是从这两个表中检索不匹配的记录。即当您说

UpdateDialogControls

u.id = a.USER_ID and a.type = 'COA' 表中,它仅与一条记录和

匹配
SJ_TEMP_ADDRESS

提供WHERE a.id IS NULL 表中不匹配的记录。 给条件SJ_TEMP_ADDRESS时也会发生同样的事情,因为alpha的类型为a.type = 'PRA',它在第二个表中匹配,因此您只会得到beta记录