我正在尝试编写一个SQL查询,该查询将根据其他几个表中的数据在一个表中收集某些数据。那部分很容易。不幸的是,我还需要从第二个表中恢复数据,这需要使用左连接来完成。
如果我只做左连接,e。克。
select *
from table_A A
left join table_B B on A.id=B.id
一切都很好。我可以足够安全地添加where子句,比如
where A.id>5
当我尝试在左侧有多个表时出现问题,例如
select *
from table_A, table_C
left join table_B on A.id=B.id
where table_A.id=table_C.id
突然之间,A.id不再是公认的专栏。我尝试更改它,以便我选择A.id作为foo,然后选择foo = B.id,但foo也不被识别。 ('on子句'中的未知列'bla')
虽然有很多引用,但解释如何进行连接子句,有些例子甚至使用简单的where子句,我找不到任何组合连接子句,where子句和多个表的子句。左手边。
关于问题的背景:
我的原始查询是:
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
不幸的是,并不能保证每个用户都会存在tutor_tutor信息 - 这是一个在网站/数据库设计周期早期不良决策中存在的一个小缺陷。因此,简单的解决方案是将其转换为连接。
问题是,我找不到任何好的教程解释如何将连接与where子句结合起来。我尽力做到以下几点:
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
答案 0 :(得分:5)
理想情况下,您不应将延迟连接语法(select ... from a,b,c
)与更具体的select ... from a join B ... join c ...
混合使用。做select *
也可能会有问题,特别是你不会使用所有字段,或者需要按名称而不是位置来引用字段。
所以你的查询应该是:
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 ...
答案 1 :(得分:3)
您可以在JOIN
中添加多个子句,例如
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
您可以在where子句中编写标准,但这是过时的表示法。但是,如果你这样做,想要在WHERE
中添加联接条款,那么添加一个OR
来处理NULL
,否则它不再是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)
答案 2 :(得分:3)
确定。很多东西......
选择* 来自table_A,table_C 在A.id = B.id上左连接table_B table_A.id = table_C.id 突然之间,A.id不再是公认的专栏。我尝试更改它,以便我选择A.id作为foo,然后选择foo = B.id,但foo也不被识别。 ('on子句'中的未知列'bla')
这个collumn问题无法识别,没有名为A的表或别名。您需要将别名放在表名前面:
select *
from table_A A, table_C
left join table_B on A.id=B.id
where table_A.id=table_C.id
但是你为什么用逗号(,)连接? 最好使用join语句。 它应该是这样的:
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'
看一下'别名' 您也可以尝试使用doc:http://dev.mysql.com/doc/refman/5.0/en/select.html
答案 3 :(得分:2)
可能需要这样的东西:
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'