2011-11-24 24 views
2

我正在嘗試編寫一個SQL查詢,它將根據跨越其他幾個表的數據收集某個表中的某些數據。這部分很容易。不幸的是,我還需要從第二張表中恢復數據,這需要通過左連接來完成。如何用where子句寫一個左連接限制多個表的左手部分?

如果我只是做一個左連接,e。 G。

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

感謝大家的所有答案;使用連接作爲'where'語句不是我以前想過的。考慮到我的培訓是在一所州立大學進行的,那裏有很多老師自己都「過時」了,所以我不會使我感到意外。 (其中一個仍然使用高架投影儀...即使有電腦投影儀可用) – RonLugge

回答

5

理想情況下,你不應該混合懶加入,更具體的select ... from a join B ... join c ...語法(select ... from a,b,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 ... 
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' 
+0

感謝您的編輯:) – dryliketoast

+0

一個很好的答案,如果我可以給兩個答案檢查,我可能會考慮這一個。反對它的最大缺陷 - 忽略最初的格式 - 是你使用純粹的左連接,其中只有一個連接應該離開。否則,你最後選擇A.id = B.id的每個案例,並從其他列中獲取數據(如果可用)。內部連接(或簡單的'連接')是合適的,因爲然後根據右側數據的可用性將結果限制在左側。 – RonLugge

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

例如

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) 
3

好的。很多東西...

SELECT * 從TABLE_A,table_C 左連接表-B上A.id = B.id 其中table_A.id = table_C.id 突然,A.id的不再是公認的專欄。我嘗試改變它,以便我選擇A.id作爲foo,然後在foo = B.id上執行,但foo也不會被識別。 (在「關於條款」未知列「BLA」)

collumn的這個問題,不承認也沒有表或別名命名答:您需要把別名表的名稱前面:

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' 

看看在「別名」。
你也可以試試這個文檔:http://dev.mysql.com/doc/refman/5.0/en/select.html

+0

感謝您的深入解答。你很正確,我草率地勾畫出來,簡化的例子在語法上是錯誤的(btw,tutor_attends.schoolid在你的中是無效的,你需要用'a'代替...:D)。有趣的是,你的左連接看起來工作正常,這表明我不明白他們的意思,以及我認爲我做的。 – RonLugge