2012-09-23 247 views
1

我試圖做JOIN語句不where子句

select * 
from buildings 
where levels = 3 
join managers; 

工作,但它在加入說錯誤。我想匹配建築物的id和manager表中的id,所以我想我想要自然連接。

+1

這是因爲語法是錯誤的。 http:// www.w3schools.com/sql/sql_join_inner.asp' –

+0

內連接是什麼SQL調用關係代數中的自然連接?我認爲join會自動加入兩個表中同名的屬性中。 – Celeritas

+1

@LewsTherin:請不要鏈接到http://w3fools.com/,他們是一個糟糕的信息來源,它已經爭取谷歌的排名達到頂峯。在這種情況下,[SELECT中的PostgreSQL文檔](http://www.postgresql.org/docs/current/static/sql-select.html)將會是一個更好的參考。 –

回答

2

如果你把在正確的地方的JOIN(FROM和WHERE之間),它是合法的寫JOIN如果沒有,那麼結果將是一個交叉連接 - 一個笛卡爾積,然後你在哪裏過濾。

這是一個非常有效的事情,儘管在這種情況下可能不是你想要的。它可以通過添加逗號分隔的表到FROM條款,如實現:

FROM buildings, managers 

這是一般都比較好風格寫一個明確的內連接當你打算加入兩個表上的條件:

SELECT * 
FROM buildings b INNER JOIN managers m ON (b.manager_id = m.manager_id) 
WHERE b.levels = 3; 

...因爲它讓其他人閱讀說明ON子句是聯接條件,而bl.levels=3是過濾器。 SQL的執行一般不關心,並且很可能轉換到上述情況:

SELECT * 
FROM buildings b, managers m 
WHERE b.levels = 3 AND b.manager_id = m.manager_id; 

內部反正,但它更容易(IMO)瞭解複雜的查詢有許多的時候,他們正在使用顯式連接語法編寫連接。

還有另外一種方式來寫你想要什麼,但它的危險和國際海事組織不應使用:

SELECT * 
FROM buildings bl 
NATURAL JOIN managers m          
WHERE bl.levels = 3; 

這JOIN的任何列that're名稱相同。調試是一場噩夢,你必須查看錶結構來理解它的功能,如果有人重命名了某列,它就會中斷,這很痛苦。不使用。見Table expressions in the PostgreSQL manual

更可接受的是USING語法還如上所述:

SELECT * 
FROM buildings bl 
INNER JOIN managers m USING (manager_id) 
WHERE bl.levels = 3; 

它匹配命名兩列manager_idJOIN S於它們的列,將它們組合成一個單一的柱,但不像NATURAL JOIN如此明確地不和沒有可怕的魔法。

我仍然喜歡寫INNER JOIN ... ON (...),但是合理的使用USING和IMO,從來沒有合理的使用NATURAL


測試表結構是:

create table managers (manager_id integer primary key); 

create table buildings (
    manager_id integer references manager(manager_id), 
    levels integer 
); 
+0

Hooray顯式連接!無論如何,這通常是進行OUTER JOIN的唯一方式(除非,AFAIK,您使用的是Sybase或其衍生產品之一併具有'* =')。 –

+0

@ muistooshort Oracle有/也有瘋狂的加入語法。他們使用了「(+)」來表示「順便說一下,我在WHERE子句中提到的這個表的連接是一個外連接,而不是我告訴你的,而不是'FROM'條款」。 ANSI連接只出現在9i中,他們在那之前堅持自己奇怪的語法。請參閱http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6585774577187,http://www.dba-oracle.com/tips_oracle_left_outer_join.htm –

1

JOIN運算符應用於表格,您應該在FROM子句中提供它。如果你這樣做,你會得到一個新的錯誤聲稱沒有JOIN條件,因爲你必須要提供ON條款後JOIN條件(這是不可選):

SELECT * 
FROM buildings b JOIN managers m ON b.managerid = m.id 
WHERE b.levels = 3 
0

,如果你想這樣做,你必須寫一樣的東西:

select * 
from bulidings b 
join managers m on b.id=m.id 
where levels = 3 

請求似乎很奇怪,但是,我相信,他們中的一個應該有一個外鍵到另一個。所以更合適的查詢將是:

select * 
from buidings b 
join managers m on b.id = m.building_id //// or b.manager_id = m.id 
where levels = 3 
-1

我想你寫的是哪個查詢是錯誤的。

所以,請儘量將

select * from buildings as bl 
    join managers as mn on bl.F_ManagerID = mn.ManagerID 
    where bl.levels = 3 

我認爲這將有助於你...

+0

這也是錯誤的 - 你嘗試過嗎?沒有'=='運算符,而你的意思是'dl.F_ManagerID'不是'bl.F_ManagerID'。無論如何,IMO更清楚地寫成「INNER JOIN ... ON」。 –

+0

謝謝你的建議。 – Rajpurohit