Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL joining three tables, join precedence

Tags:

sql

I have three tables: R, S and P.

Table R Joins with S through a foreign key; there should be at least one record in S, so I can JOIN:

SELECT         *     FROM          R     JOIN    S ON (S.id = R.fks) 

If there's no record in S then I get no rows, that's fine.

Then table S joins with P, where records is P may or may not be present and joined with S.

So I do

SELECT         *     FROM          R     JOIN    S ON (S.id = R.fks)     LEFT JOIN P ON (P.id = S.fkp) 

What if I wanted the second JOIN to be tied to S not to R, like if I could use parentheses:

SELECT         *     FROM          R     JOIN    (S ON (S.id = R.fks) JOIN P ON (P.id = S.fkp)) 

Or is that already a natural behaviour of the cartesian product between R, S and P?

like image 217
vulkanino Avatar asked Sep 23 '10 15:09

vulkanino


People also ask

Does it matter what order you join tables in SQL?

For INNER joins, no, the order doesn't matter. The queries will return same results, as long as you change your selects from SELECT * to SELECT a. *, b. *, c.

Does the order of joins affect performance?

Even though the join order has no impact on the final result, it still affects performance. The optimizer will therefore evaluate all possible join order permutations and select the best one.

Can you join 3 tables in SQL?

It is possible to use multiple join statements together to join more than one table at the same time. To do that you add a second INNER JOIN statement and a second ON statement to indicate the third table and the second relationship.

Which join is faster left or right?

However, if you change the matching key in the join query from Name to ID and if there are a large number of rows in the table, then you will find that the inner join will be faster than the left outer join.


1 Answers

All kinds of outer and normal joins are in the same precedence class and operators take effect left-to-right at a given nesting level of the query. You can put the join expression on the right side in parentheses to cause it to take effect first. Remember that you will have to move the ON clauses around so that they stay with their joins—the join in parentheses takes its ON clause with it into the parentheses, so it now comes textually before the other ON clause which will be after the parentheses in the outer join statement.

(PostgreSQL example)

In SELECT * FROM a LEFT JOIN b ON (a.id = b.id) JOIN c ON (b.ref = c.id);

the a-b join takes effect first, but we can force the b-c join to take effect first by putting it in parentheses, which looks like:

SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);

Often you can express the same thing without extra parentheses by moving the joins around and changing the direction of the outer joins, e.g.

SELECT * FROM b JOIN c ON (b.ref = c.id) RIGHT JOIN a ON (a.id = b.id);

like image 172
rakslice Avatar answered Sep 25 '22 14:09

rakslice