views:

587

answers:

6
+1  Q: 

Mysql join syntax

If I want to perform joins on 3 or more tables, what is the best syntax? This is my attempt:

Select * 
from table1 
inner join table2 using id1, table2 
inner join table3 using id2, table3 
inner join table4 using id4 
where table2.column1="something" 
and table3.column4="something_else";

does that look right? The things I'm not sure about are 1) do I need to seperate the joins with a comma 2) am I right to make all my joins first and then put my conditions after that? 3) would I be better to use sub-queries and if so what is the corect syntax

Thanks for any advice!

A: 

1) do I need to seperate the joins with a comma

No

2) am I right to make all my joins first and then put my conditions after that?

Yes

3) would I be better to use sub-queries and if so what is the corect syntax

No. Joining tables is the preferred and correct way.

Philippe Gerber
+1  A: 
  1. Joins are not separated by a comma
  2. ANSI syntax puts the joins first then where condition

e.g. SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id WHERE table2.column1='Something'

  1. I'm not 100% sure what you are trying to achieve. But it looks like you do not need to use subqueries.

A subquery would be executed for every row, it sounds as though you could run a more efficient query just using inner joins.

Hope that helps. If you can elaborate a little I will provide more explanation.

Simon
The third number 1 should be a 3 the counter has got screwy.
Simon
For multiple joins no commas, SELECT * FROM table1 T1 JOIN table2 T2 ON T1.id =T2.id JOIN table3 ON T1.id = T3.id
Simon
A: 

Remove the comma's and the duplicate table names, like:

Select * 
from table1 
inner join table2 using id1
inner join table3 using id2
inner join table4 using id4 
where table2.column1="something" 
and table3.column4="something_else"

If id4 has a different name in table1, explicitly name the join condition, for example:

inner join table4 on table4.id = table1.table4i
Andomar
A: 

Given your requirement that table2 gets joind on the id1-columns in table1 and table2, table3 gets joind on the id2-columns in table2 and table3 and table4 gets joind on the id3-columns in table3 and table4 you'll have to do:

SELECT * 
FROM table1 
INNER JOIN table2 ON table2.id1 = table1.id1
INNER JOIN table3 ON table3.id2 = table2.id2
INNER JOIN table4 ON table4.id3 = table3.id3
WHERE table2.column1 = "something" 
    AND table3.column4 = "something_else"

I think this statement is much more clearer on what is exactly joined in which way - compared to the USING-statement.

Stefan Gehrig
I like this but wanted to check something. At the moment the tables are joined in sequence. If I wanted to join t1 to t2 then t3 to t2 but then t4 to t2 NOT t3. Can I do that? Does it matter as to the order of the joins?
The order of the joins normally doesn't matter and will be changed the MySQL query optimzer in almost all cases. You can reorder them as you wish.
Stefan Gehrig
+2  A: 
  1. Try to avoid using * where possible.
    Specify exactly the data you want returned.

  2. Format your queries using a standard style.
    Pick a style you like and keep to it.
    You will thank yourself later when your queries get more complex.

  3. Most optimizers will recognize when a condition in a WHERE clause implies an INNER JOIN, but there's no reason not to code that explicitly; if nothing else it keeps your WHERE clause manageable.

  4. Be explicit about what columns you join on. Be explicit about the type of join you're using. USING seems like a shortcut that could get you into trouble.

  5. MySQL has traditionally not handled subqueries as well as could be hoped. That may be changing in newer versions, but there are other ways to get your data without relying on them.

Welcome to the wonderful world of relational databases!

select t1.*
       , t2.*
       , t3.*
       , t4.*

from   table1 t1

       inner join table2 t2
       on t1.id = t2.t1_id
    and
       t2.column1 = "something"

       inner join table3 t3
       on t2.id = t3.t2_id
    and
       t3.column4 = "something_else"

       inner join table4 t4
       on t3.id = t4.t3_id;
Adam Bernier
I'm a little confused by your syntax. Do I not need WHERE aswell as AND? Also, should I place the conditions that relate to a particular table with the join that also refers to that table?
Think a bit about what it means to say WHERE t2.column1 = 'something': you want only rows from t2 where column1 is 'something' in the \entire\ query. Since that's the case, you can go right ahead and specify that as a condition of your JOIN. If you wanted a blank row when t2.column1 didn't contain 'something' you would change the join from INNER to LEFT OUTER, keeping the second join condition. As soon as you specify in WHERE that you want t2.column1 = "something" then you have an implicit INNER JOIN, and that condition can be moved up to the FROM clause.
Adam Bernier
A: 

You may be able to use natural join which joins on field names common to the tables you want to join as follows.

SELECT * FROM table1 NATURAL JOIN table2 NATURAL JOIN table3 NATURAL table4 WHERE table2.column1 = "something" AND table3.column4 = "something_else"