WHERE子句中具有条件的LEFT JOIN与ON中的相同LEFT JOIN不等同的原因和原因是什么?

Kam*_*Keb 21 sql t-sql sql-server left-join

我遇到了一个非常令人困惑的情况,这使我质疑我对SQL Server中的连接的理解.

SELECT t1.f2 
FROM   t1 
LEFT JOIN t2 
ON t1.f1 = t2.f1 AND cond2 AND t2.f3 > something 
Run Code Online (Sandbox Code Playgroud)

不会给出相同的结果:

SELECT t1.f2 
FROM   t1 
LEFT JOIN t2 
ON t1.f1 = t2.f1 AND cond2 
WHERE  t2.f3 > something 
Run Code Online (Sandbox Code Playgroud)

可以通过告诉这两个查询是否应该是等价的来取悦某人的帮助吗?

谢谢

And*_*mar 33

在查找匹配行时on使用该子句join.该where子句用于在完成所有连接后过滤行.

迪士尼卡通投票给总统的一个例子:

declare @candidates table (name varchar(50));
insert @candidates values 
    ('Obama'), 
    ('Romney');
declare @votes table (voter varchar(50), voted_for varchar(50));
insert @votes values 
    ('Mickey Mouse', 'Romney'),
    ('Donald Duck', 'Obama');

select  *
from    @candidates c
left join    
        @votes v
on      c.name = v.voted_for
        and v.voter = 'Donald Duck'
Run Code Online (Sandbox Code Playgroud)

Romney即使Donald没有投票给他,这仍然会返回.如果将条件从子句移动onwhere子句:

select  *
from    @candidates c
left join    
        @votes v
on      c.name = v.voted_for
where   v.voter = 'Donald Duck'
Run Code Online (Sandbox Code Playgroud)

Romney 将不再出现在结果集中.

  • 请注意,此示例使用的是OUTER连接,在这种情况下,这两个代码段在功能上并不等效。 (2认同)

Joh*_*Woo 17

两者都完全不同.

第一个查询在表t2的连接发生之前对表进行过滤.因此,结果将在表格上加入,t1结果所有记录都t1将显示在列表中.

第二个过滤完表后的总结果.


这是一个例子

表格1

ID   Name
1    Stack
2    Over 
3    Flow
Run Code Online (Sandbox Code Playgroud)

表2

T1_ID   Score
1       10
2       20
3       30
Run Code Online (Sandbox Code Playgroud)

在您的第一个查询中,它看起来像这样,

SELECT  a.*, b.Score
FROM    Table1 a
        LEFT JOIN Table2 b
           ON a.ID = b.T1_ID AND
              b.Score >= 20
Run Code Online (Sandbox Code Playgroud)

它的作用是在加入表格之前,table2首先按分数过滤记录.因此,将在table1上加入的唯一记录是

T1_ID   Score
2       20
3       30
Run Code Online (Sandbox Code Playgroud)

因为Scoreof T1_ID只有10.查询的结果是

ID   Name    Score
1    Stack   NULL
2    Over    20
3    Flow    30
Run Code Online (Sandbox Code Playgroud)

而第二个查询是不同的.

SELECT  a.*, b.Score
FROM    Table1 a
        LEFT JOIN Table2 b
           ON a.ID = b.T1_ID
WHERE   b.Score >= 20
Run Code Online (Sandbox Code Playgroud)

它首先连接记录是否在另一个表上有匹配的记录.结果将是

ID   Name    Score
1    Stack   10
2    Over    20
3    Flow    30
Run Code Online (Sandbox Code Playgroud)

并进行过滤b.Score >= 20.所以最终的结果将是

ID   Name    Score
2    Over    20
3    Flow    30
Run Code Online (Sandbox Code Playgroud)