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!
Try to avoid using * where possible.
Specify exactly the data you want returned.
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.
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.
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.
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;
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.
Joins are not separated by a comma
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'
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.
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.
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
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"
Related
This question is different than the ones I have seen already answered. Is it possible to left join using multiple 'FROM' tables? When I try it (with other code, but the principle is the same) I get the error 'Unknown column 'table1.otherId' in 'on clause'. Any help would be greatly appreciated.
Something like this:
SELECT *
FROM table1, table2
LEFT JOIN other_table
ON other_table.id = table2.id
AND other_table.otherId = table1.otherId
Try like this:-
SELECT *
FROM table1
LEFT JOIN other_table
ON table1.id=other_table.id LEFT JOIN table2 ON
other_table.otherId = table2.id
It depends what you want to do. You seem to want a Cartesian product of the first two tables with lookups on the third:
SELECT *
FROM table1 CROSS JOIN
table2 LEFT JOIN
other_table
ON other_table.id = table2.id AND
other_table.otherId = table1.otherId;
Commas -- which should just be banned permanently from FROM clauses -- are similar to CROSS JOINs. However, the parsing of the SQL statement is different. A comma prevents the tables before it from being used in ON clauses after it; that is the source of your error.
Answer is "No"
But you can do it this way:
SELECT * FROM table2, other_table ON other_table.id = table2.id
LEFT JOIN table1 ON other_table.otherId = table1.otherId
I am working on some other developers code and need to simplify this query which is in the format below.
SELECT
table1.id, table2.userid, table4.groupid
FROM
table1, table2, table3, table4
WHERE
userid = table4_userid
and
table2.id = table3.table2_id
and
table1.table3_id = table3.id
and
table3.statement_id = 264803
order by table4_groupid
But I am used to join queries by explicitly mentioning the join type i.e. LEFT, RIGHT OR OUTER join. I also use TableName.TableField so that I know which field is from which table. However, as you can see above it's a bit of mix of tablename.tablefield and just tablefield. The above query is working fine but I need to make table4 as a LEFT JOIN so that if there aren't any matching rows in table4 it should still show some data.
My questions are:
1) What types of joins are above?
2) How do I change the above query to make table4 as a LEFT JOIN?
I know you may want the original query but I need just little pointers towards right direction and I will do the rest myself.
Since you are using the tables directly in the where statement, it will be considered ordinary INNER JOINs. Using the where statement for joining table are the old way of joining and much harder to read. If you would like to LEFT JOIN table4, I suggest that you to rewrite the query like this:
SELECT
table1.id,
table2.userid,
table4.groupid
FROM
table1
JOIN table3
ON table1.table3_id = table3.id
JOIN table2
ON table2.id = table3.table2_id
LEFT JOIN table4
ON table2.userid = table4_userid
WHERE
table3.statement_id = 264803
order by
table4_groupid
Looking at the conditions after the WHERE all the above are inner joins.
Try this one, I am not sure of the ONs as we don't really know the tables' structures:
SELECT
t1.id, t2.userid, COALESCE(t4.groupid, 0)
FROM
table1 t1 INNER JOIN table3 t3 ON t1.table3_id=t3.id
INNER JOIN table2 t2 ON t2.id=t3.table2_id
LEFT JOIN table4 t4 ON t1.userid=t4.table4_userid
WHERE
t3.statement_id = 264803
order by t4.groupid
I have 5 Tables like this:
TABLE 1: PRIMARY_KEY,NAME,FK_TABLE2
TABLE 2: PRIMARY_KEY,FK_TABLE3
TABLE 3: PRIMARY_KEY,FK_TABLE4
TABLE 4: PRIMARY_KEY,FK_TABLE5
TABLE 5: PRIMARY_KEY,DIAGRAM_NAME
And what I want is when I search for a name in a search bar, it returns Name from Table1, and also DIAGRAM_NAME from table 5.
The first part is easy:
SELECT `TABLE1`.name
from Table 1
Where `TABLE1`.name LIKE '%$search%'
But for the second part I need your help...
Thank you!
You need to look into using JOIN:
SELECT T.Name, T5.Diagram_Name
FROM Table1 T
JOIN Table2 T2 ON T.FK_TABLE2 = T2.PRIMARY_KEY
JOIN Table3 T3 ON T2.FK_TABLE3 = T3.PRIMARY_KEY
JOIN Table4 T4 ON T3.FK_TABLE4 = T4.PRIMARY_KEY
JOIN Table5 T5 ON T4.FK_TABLE5 = T5.PRIMARY_KEY
WHERE T.Name LIKE '%$search%'
If you want to return the names that don't have matching diagram names, use LEFT JOIN instead.
Good luck.
You are going to need to JOIN the tables using the Primary Key and FK values:
select t1.name, t5.DIAGRAM_NAME
from table1 t1
left join table2 t2
on t1.FK_TABLE2 = t2.PRIMARY_KEY
left join table3 t3
on t2.FK_TABLE2 = t3.PRIMARY_KEY
left join table4 t4
on t3.FK_TABLE3 = t4.PRIMARY_KEY
left join table5 t5
on t4.FK_TABLE4 = t5.PRIMARY_KEY
Where t1.name LIKE '%$search%'
If you need help learning JOIN syntax, here is a great visual explanation of joins.
I used a LEFT JOIN in my example query, which will return all rows from table1 even if there is not a matching row in the remaining tables.
If you know that there is a matching row in all of the tables that you are joining, then you can use an INNER JOIN.
What is the best way to join 2 tables where the second table has an id and a keyword to join?
my try :
SELECT id, name
FROM table1
LEFT JOIN table2 ON (table1.id = table2.id AND table2.id = 'myKeyword')
WHERE ...
Is there a way to handle the search / join of the keyword in the WHERE clause?
Placing table2.id = 'myKeyword' in the where clause will negate the LEFT JOIN
This is quite appropriate as you have it.
Maybe with a little more detail we can see what you are getting at.
SELECT {column_list}
FROM table1 t1, table2 t2
WHERE t1.id = t2.id
AND {some_column_from_either_table} = 'myKeyword';
I can do it in sybase and I can do it in oracle, but I'm not seeing how to do it in mysql.
I've got this:
(please restrain yourself from re-formatting my sql, last time somebody did that they changed it so it wasn't the same and made the question meaningless)
select table1.id
from
table1
inner join
table2 on (table1.id = table2.id and table2.data='cat'),
table1 t1
left outer join
table3 on (t1.id = table3.id and table3.data = 'dog')
And I get all sorts of results that make no sense.
I want to get a list of all of the id's from table1 where table2.data = cat, then do an outer join with the results of that against table 3 where table3.data = dog.
I notice that I can't specify the same table/alias for table1 in the two join clauses, so that leads me to believe that mysql is running the join expressions separately and ORing the results together or something like that.
I also tried getting rid of the "inner join" in the from section and putting it in the where clause, that didn't work either, though it didn't work in a different way (got different erroneous results)
This would be so easy in sybase or oracle.
What am I doing wrong?
select table1.id
from
table1
inner join
table2 on (table1.id = table2.id and table2.data='cat')
left outer join
table3 on (table1.id = table3.id and table3.data = 'dog')
I think you never want to use a comma in the from statement. I believe the comma is equivalent to saying cross join. Not sure though, but I think this query is what you're looking for.