究竟如何应用left join on子句

时间:2015-07-06 11:32:00

标签: sql

我对如何在左连接中应用on子句感到有点困惑。据我所知,on子句类似于where子句,但是在实际连接之前应用,而不是在where子句之后应用。

但是,我试图限制连接左表中的记录数量,包括on子句中的条件,但我仍然从左侧获得所有记录。

以下是一个例子:

Table A
a    b
-------
1   100
2   200
3   300
4   400

Table B
z    y
-------
200 20000
300 30000

我正在做的查询是:

select *
from A a
    left join Z z
        on a.b = z.z
            and a.a in (1, 2, 3);

但是在结果中我仍然得到a.a = 4的行,为什么?做一个where子句解决了这个问题,但我正在尽快摆脱这些记录(在其他人加入的真实场景查询中)。

Result
------
1   100 NULL    NULL
2   200 200 20000
3   300 300 30000
4   400 NULL    NULL

2 个答案:

答案 0 :(得分:2)

SQL语句描述结果集。它们没有准确指定结果的计算方式。

对于left join,规则是保留第一个表中的所有行,然后保留第二个表中的所有匹配行。无论on子句的计算结果为true,false还是NULL,都是如此。

所以,如果你这样做:

select *
from A a left join
     Z z
     on 1 = 0

然后您将获得A表中的所有行,即使on子句总是评估为false。 Z中的列都将为NULL

如果你这样做:

select *
from A a left join
     Z z
     on a.b = z.z and a.a in (1, 2, 3);

然后你仍然获取第一个表中的所有行。

简单的规则是第一个表中的条件进入where,第二个(和后续)表中的条件进入on

select *
from A a left join
     Z z
     on a.b = z.z 
where a.a in (1, 2, 3);

规则与right join完全相反。对于inner加入,如果条件符合onwhere,则无关紧要。对于full outer join。 。 。那么你经常会发现自己使用子查询。

答案 1 :(得分:0)

应该是正确的加入。以下查询返回2行

选择* 来自A a     右边加入B z         在a.b = z.z             和(1,2,3)中的a.a;