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 по дате отправления: