Re: RIGHT JOIN Table Ordering Question - Mailing list pgsql-sql

From Tom Lane
Subject Re: RIGHT JOIN Table Ordering Question
Date
Msg-id 1525.1009750525@sss.pgh.pa.us
Whole thread Raw
In response to RIGHT JOIN Table Ordering Question  (Tara Piorkowski <tara@vilaj.com>)
List pgsql-sql
Tara Piorkowski <tara@vilaj.com> writes:
> I have a question about the ordering of joining of tables using the 
> RIGHT JOIN syntax in the FROM clause of a query. Specifically, I've 
> noticed that if I have one table on which I attempt to right join to two 
> other tables, the ordering of the join conditions is important

Yup, it sure is.  Outer joins are not associative (nor commutative,
obviously).  When you write (a RIGHT JOIN b) RIGHT JOIN c, you first
have the result of the A/B join, which will be guaranteed to produce all
the joined rows an inner join would produce, plus a row with null A
values for each otherwise unmatched B row.  Then you take this and join
it to C, again adding rows for each unmatched C row.  This is not
associative because what's matched or not in the second step may depend
on what got added in the first step.  In your example, try looking at
the whole join results without any WHERE filter:

regression=# select * from goal_progress_notes a
regression-# RIGHT JOIN goals c USING (goal_id);goal_id | goal_prog_note_id | rating_id |      statement      |
     statement
 
---------+-------------------+-----------+---------------------+----------------------------------------      1 |
         1 |         1 | Tara is doing well. | Will write a correct SQL92 LEFT JOIN.      2 |                   |
   |                     | Will write a correct SQL92 RIGHT JOIN.
 
(2 rows)

regression=# select * from goal_progress_notes a
regression-# RIGHT JOIN goals c USING (goal_id)
regression-# RIGHT JOIN progress_ratings b USING (rating_id);rating_id | goal_id | goal_prog_note_id |      statement
  |               statement               | description
 
-----------+---------+-------------------+---------------------+---------------------------------------+--------------
     1 |       1 |                 1 | Tara is doing well. | Will write a correct SQL92 LEFT JOIN. | Achieved        2
|        |                   |                     |                                       | Not Achieved
 
(2 rows)

I would imagine that what you really want in this example is(goals c LEFT JOIN goal_progress_notes a USING (goal_id))
LEFT JOIN progress_ratings b USING (rating_id)
 
since you definitely want an output row for every goals row whether
there are notes or not, and you don't really want output rows for
progress ratings that happen to not be used currently (do you)?
Depending on your viewpoint about goal progress notes that don't
match any goal, perhaps the first join should be a FULL join.

> understanding fully the RIGHT JOIN/LEFT JOIN sequence (I originally come 
> from an Oracle SQL background, which is different)

AFAIK Oracle has the same semantics for left/right joins, just an
obscure syntax.
        regards, tom lane


pgsql-sql by date:

Previous
From: Tara Piorkowski
Date:
Subject: RIGHT JOIN Table Ordering Question
Next
From: "Aasmund Midttun Godal"
Date:
Subject: Unpredictable text -> date implicit casting behaviour/to_date bug