1

这个查询:

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(+)

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

4

2 回答 2

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 语法除了更易于移植之外,可能更易于解释,因此通常是首选。

于 2012-09-17T16:25:22.890 回答
1

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

尝试

select * 
from table_a
     left join table_b 
     on table_a.id=table_b.id
     and table_b.name='BENEFICIARY'
于 2012-09-17T15:46:18.283 回答