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')

一般に、古い構文を使用している場合、結合の外で適用される述語ではなく、結合条件の一部にする述語には、(+)演算子を適用する必要があります。ON同様に、ANSI 構文を使用しているときに結合条件の一部にする述語は、句の一部にする必要があります。

この場合、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 に答える