Re: RIGHT JOIN Table Ordering Question

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: RIGHT JOIN Table Ordering Question
Дата
Msg-id 1525.1009750525@sss.pgh.pa.us
обсуждение исходный текст
Ответ на RIGHT JOIN Table Ordering Question  (Tara Piorkowski <tara@vilaj.com>)
Список 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 по дате отправления:

Предыдущее
От: Tara Piorkowski
Дата:
Сообщение: RIGHT JOIN Table Ordering Question
Следующее
От: "Aasmund Midttun Godal"
Дата:
Сообщение: Unpredictable text -> date implicit casting behaviour/to_date bug