我可以为不属于连接的LEFT JOIN子句添加条件吗?

时间:2017-11-08 18:33:58

标签: sql postgresql join left-join

在我看来,这两个查询都会返回相同的结果:

SELECT * FROM table1 
  LEFT JOIN table2 ON table1.key = table2.key AND table2.foo = 1

SELECT * FROM table1 
  LEFT JOIN table2 ON table1.key = table2.key
  WHERE table2.foo = 1

这是对的吗?如果是这样,它们之间是否存在任何有意义的差异?

3 个答案:

答案 0 :(得分:3)

他们会返回相同的结果。

第一个查询将包含table1中的记录,即使foo为1也没有匹配的table2记录。

第二个查询将包含来自table1的记录,其中没有匹配的table2记录,其foo值为1.

这种模式(LEFT JOIN t ON id=id and other='literal')很常见。例如,在我目前使用的系统中,我们有一个address_master表,其中person_id列为匹配地址的人员,addr_cde(地址代码)列告诉您什么样的地址(家庭,工作,度假等)。所以看到像这样的联接是很常见的:

 LEFT JOIN address_master a ON a.person_id = Person.Id AND a.addr_cde = 'Work'

如果我们将addr_cde = 'Work'表达式移到WHERE子句,那么即使我们想要查看该人的其他数据。

答案 1 :(得分:2)

这不正确

如果我们假设下面的样本数据,则结果不一样:

T1
KEY
---
 1  
 2  

T2
KEY Foo
--- ---
 1  1
 2  4


SELECT * FROM table1 
  LEFT JOIN table2 ON table1.key = table2.key AND table2.foo = 1

T1.KEY  T2.KEY  T2.Foo
------  ------  ------
1       1       1
2       NULL    Null

SELECT * FROM table1 
  LEFT JOIN table2 ON table1.key = table2.key
  WHERE table2.foo = 1

T1.KEY  T2.KEY  T2.Foo
------  ------  ------
1       1       1

答案 2 :(得分:1)

The following shows how the 2 queries are different:   

    declare @t1 table(id int);
    insert into @t1 values (1), (2);

    declare @t2 table(id int, col int);
    insert into @t2 values(1,1), (3,1);
  1. 第一个示例 - 右表上具有Where过滤器的LEFT连接:

    select *
    from @t1 t1 
    left join @t2 t2
    on t1.id = t2.id
    where t2.col = 1; 
    
  2. 正确的LEFT连接,用于过滤ON子句中的右表:

    select *
    from @t1 t1 
    left join @t2 t2
    on t1.id = t2.id 
    AND t2.col = 1;
    
  3. INNER JOIN。这给出了与第一个例子相同的结果 - LEFT JOIN和Where子句中右表的过滤器:

    select *
    from @t1 t1 
    join @t2 t2
    on t1.id = t2.id
    where t2.col = 1;