Oracle外连接没有给出预期的结果(表现得像内连接)

时间:2012-09-17 15:42:46

标签: sql oracle11g inner-join outer-join

此查询:

select *
from table_a
, table_b
where table_a.id = table_b.id(+)
   and table_b.name = 'BENEFICIARY'

给我留下没有记录。 table_b没有name ='BENEFICIARY'的记录。但是外连接应该返回table_a中的所有记录。没有? 以下查询按预期返回table_a中的记录:

select *
from table_a
, (select *
   from table_b
   where table_b.name = 'BENEFICIARY') AS table_b1
where table_a.id = table_b1.id(+)

为什么第一个查询没有返回记录?

2 个答案:

答案 0 :(得分:4)

旧式语法查询

select *
 from table_a
    , table_b
where table_a.id = table_b.id(+)
  and table_b.name = 'BENEFICIARY'

与ANSI查询

相同
select *
 from table_a
      left outer join table_b on (table_a.id = table_b.id)
where table_b.name = 'BENEFICIARY'

在这两种情况下,谓词table_b.name = 'BENEFICIARY'都是在连接之后应用的,而不是作为连接的一部分,这会破坏进行外连接的目的。为了确保谓词是连接操作的一部分,使用旧语法,您需要

select *
 from table_a
    , table_b
where table_a.id = table_b.id(+)
  and table_b.name(+) = 'BENEFICIARY'

使用ANSI语法时,您需要

select *
 from table_a
      left outer join table_b on (    table_a.id = table_b.id 
                                  and table_b.name = 'BENEFICIARY')

通常,如果您使用旧语法,那么您希望成为连接条件一部分的任何谓词而不是在连接外部应用的谓词都需要(+)运算符适用于它。类似地,当您使用ANSI语法时,您希望成为连接条件一部分的谓词需要成为ON子句的一部分。

在这种情况下,除了更具可移植性之外,ANSI语法可能更加不言自明,因此通常首选。

答案 1 :(得分:1)

在第一个查询中,过滤器将在连接后应用于结果。

尝试

select * 
from table_a
     left join table_b 
     on table_a.id=table_b.id
     and table_b.name='BENEFICIARY'
相关问题