Reputation: 5174
I'm trying to write an SQL query that will gather certain data in one table, based on data across several other tables. That part was easy enough. Unfortunately, I also need to recover data from a second table, and that needs to be done with a left join.
If I just do a left join, e. g.
select *
from table_A A
left join table_B B on A.id=B.id
everything is fine. I can add in a where clause safely enough, like
where A.id>5
The issue occurs when I try to have more than one table on the left hand side, for example
select *
from table_A, table_C
left join table_B on A.id=B.id
where table_A.id=table_C.id
All of a sudden, A.id is no longer a recognized column. I tried changing it so that I have select A.id as foo, and then do on foo=B.id, but foo isn't recognized either. ( Unknown column 'bla' in 'on clause')
While there are many references out there than explain how to do a join clause, and some examples even use a simple where clause, I can't find any that combine a join clause, a where clause, and multiple tables on the left hand side.
For background on the question:
My original query was:
select SQL_CALC_FOUND_ROWS tutor_user.username
, tutor_user.userid
, tutor_tutor.rate
, tutor_user.username
from tutor_user
, tutor_attends
, tutor_tutors_in
, tutor_subject
, tutor_tutor
where tutor_user.userid=tutor_attends.userid
and tutor_attends.schoolid=80
and tutor_tutors_in.userid=tutor_user.userid
and tutor_tutors_in.subjectid=tutor_subject.subjectID
and tutor_subject.name='Aerospace Studies'
and tutor_tutor.userid=tutor_user.userid //ERROR
LIMIT 0, 15
Unfortunately, there's no guarantee that tutor_tutor information will exist for every user -- a minor flaw that's persisting from poor decisions early on in the website/database design cycle. So, the easy solution is to turn it into a join.
The problem is, I can't find any good tutorials explaining how to combine a join with where clauses. My best effort comes up with the following:
select SQL_CALC_FOUND_ROWS tutor_user.username
, tutor_user.userid
, tutor_tutor.rate
, tutor_user.username
from tutor_user
, tutor_attends
, tutor_tutors_in
, tutor_subject
LEFT JOIN tutor_tutor
on tutor_user.userid=tutor_tutor.userid
where tutor_user.userid=tutor_attends.userid
and tutor_attends.schoolid=80
and tutor_tutors_in.userid=tutor_user.userid
and tutor_tutors_in.subjectid=tutor_subject.subjectID
and tutor_subject.name='Aerospace Studies'
LIMIT 0, 15
Upvotes: 2
Views: 23815
Reputation: 2118
ok. A lot of stuff...
select * from table_A, table_C left join table_B on A.id=B.id where table_A.id=table_C.id All of a sudden, A.id is no longer a recognized column. I tried changing it so that I have select A.id as foo, and then do on foo=B.id, but foo isn't recognized either. ( Unknown column 'bla' in 'on clause')
This problem of collumn not recognized there is no table or alias named A. You need to put the alias in front of table's name:
select *
from table_A A, table_C
left join table_B on A.id=B.id
where table_A.id=table_C.id
But why are you using join with a comma (,)?
It's better use join statement.
It should be something like this:
select * /* any collmn you want */
from tutor_user u
left join tutor_attends a ON a.userid = u.userid
left join tutor_tutors_in t ON t.userid = u.userid
left join tutor_subject s ON s.subjectid = t.subjectid
LEFT JOIN tutor_tutor tt on u.userid = tt.userid
where tutor_attends.schoolid=80
and tutor_subject.name='Aerospace Studies'
Take a look on 'alias'.
Also you can try the doc: http://dev.mysql.com/doc/refman/5.0/en/select.html
Upvotes: 3
Reputation: 153
Probably need something like this:
select A.*, B.field1, C.field3 from A
left join B on A.id=B.id
left join C on A.id=C.id
where C.field5 = 'foo'
Upvotes: 2
Reputation: 23982
You can put multiple clauses in the JOIN
e.g.
SELECT *
FROM table_a A
LEFT OUTER JOIN table_b B
ON A.col1 = B.col1
AND A.col2 = B.col2
AND B.col3 > 5
You can write the criteria in the where clause, but that is outdated notation. If you do, however, want to pu the join clause in the WHERE
anyway then add an OR
to handle NULL
otherwise it ceases to be a LEFT JOIN
e.g.
SELECT *
FROM table_a A
LEFT OUTER JOIN table_b B
ON A.col1 = B.col1
AND A.col2 = B.col2
WHERE (B.col3 > 5 OR B.col3 IS NULL)
Upvotes: 3
Reputation: 360702
Ideally, you shouldn't mix the lazy join syntax (select ... from a,b,c
) with the more specific select ... from a join B ... join c ...
. And doing a select *
can be problematic as well, especially you're not going to be using all of the fields, or need to refer to the fields by name instead of position.
So your query should be:
SELECT A.field, A.otherfield, B.field, B.otherfield, C.yetanotherfield
FROM table_A AS A
JOIN table_B as B on A.id = B.a_id
JOIN table_C as C on B.id = C.b_id
WHERE ...
Upvotes: 5