Reputation: 17107
This query:
select *
from table_a
, table_b
where table_a.id = table_b.id(+)
and table_b.name = 'BENEFICIARY'
returns me no records. table_b has no records with name='BENEFICIARY'. But the outer join should return all records from table_a regardless . No? The below query returns records from table_a as expected:
select *
from table_a
, (select *
from table_b
where table_b.name = 'BENEFICIARY') AS table_b1
where table_a.id = table_b1.id(+)
Why is the first query not returning records?
Upvotes: 1
Views: 972
Reputation: 231851
The old-style syntax query
select *
from table_a
, table_b
where table_a.id = table_b.id(+)
and table_b.name = 'BENEFICIARY'
is identical to the ANSI query
select *
from table_a
left outer join table_b on (table_a.id = table_b.id)
where table_b.name = 'BENEFICIARY'
In both cases, the predicate table_b.name = 'BENEFICIARY'
is applied after the join, not as part of the join, which defeats the purpose of doing an outer join. In order to ensure that the predicate is part of the join operation, using the old syntax, you would need
select *
from table_a
, table_b
where table_a.id = table_b.id(+)
and table_b.name(+) = 'BENEFICIARY'
while with ANSI syntax, you would want
select *
from table_a
left outer join table_b on ( table_a.id = table_b.id
and table_b.name = 'BENEFICIARY')
In general, if you're using the old syntax, any predicate that you want to be part of the join condition rather than a predicate that is applied outside of the join, would need to have the (+)
operator applied to it. Similarly, a predicate that you want to be part of the join condition when you are using ANSI syntax would need to be part of the ON
clause.
In this case, the ANSI syntax is likely to be more self-explanatory in addition to being more portable so it would generally be preferred.
Upvotes: 4
Reputation: 51514
In the first query, the filter is being applied to the results, after the join.
Try
select *
from table_a
left join table_b
on table_a.id=table_b.id
and table_b.name='BENEFICIARY'
Upvotes: 1