Clodoaldo Neto
Clodoaldo Neto

Reputation: 125284

Condition in an OUTER JOIN gives different result as in WHERE condition

While trying an outer join query I noticed that changing one condition from the where clause to the join clause changes the result. That surprised me but I simplified the tables and the query as below and now I think I understand but I would like to hear a solid explanation.

create table t0 (id int, b int);
create table t1 (id int, b int);
insert into t0 (id, b) values (1, 10), (2, 10);
insert into t1 (id, b) values (1, 2);

select t0.id, t0.b
from t0
left outer join t1 on 
    t0.id = t1.id
where
    t0.b = 10
    and
    t1.b = 2
;
 id | b  
----+----
  1 | 10
(1 row)

Now I move one of the conditions from the where to the join clause:

select t0.id, t0.b
from t0
left outer join t1 on 
    t0.id = t1.id
    and
    t1.b = 2
where 
    t0.b = 10
;
 id | b  
----+----
  1 | 10
  2 | 10
(2 rows)

Do you know how to write a straight reasoning?

Upvotes: 1

Views: 89

Answers (1)

Andomar
Andomar

Reputation: 238116

The on condition of an outer join only determines if the join succeeds. If the join fails, the joined columns are filled with null.

On the other hand, a where clause filters entire rows out of the result set.

To make this more clear, addd t1.b to the result set. With t1.b = 2 as a where condition, you get:

t0.id   t0.b   t1.id   t1.b
1       10     1       2

versus t1.b = 2 as an on condition::

t0.id   t0.b   t1.id   t1.b
1       10     1       2
2       10     NULL    NULL

You can see why the where clause filters the second row out: null = 2 is not true.

Upvotes: 6

Related Questions