2011-09-09 132 views
7

我們可以得到同樣的結果在這兩個方面..哪個更好..左外連接還是右外連接?

Table_1 LEFT OUTER JOIN Table_2 

Table_2 RIGHT OUTER JOIN Table_1 

如果我們能得到同樣的結果爲什麼要使用右外連接?哪一個更好 ?

+7

總結'a'和'b',你可以做'a + b'或'b + a'。哪一個更好? –

+0

我認爲一個現代的關係數據庫管理系統可以將一個轉換爲另一個,並選擇一個性能更好的應用程序,因此應該沒有關係。 –

回答

13

正如其他人已指出LEFT OUTER JOINRIGHT OUTER JOIN是完全一樣的操作,除了與他們的觀點相反。你的問題就像詢問寫a < b還是b > a是更好。他們是一樣的 - 這只是一個偏好問題。

話雖如此,我發現大多數人更熟悉LEFT JOIN並在SQL中一致地使用它。如果在查詢中突然出現RIGHT JOIN,有些人甚至覺得很難閱讀,並且導致他們不得不停下來思考它的含義。所以我建議,如果在兩個選項之間有相同的選擇,那麼更喜歡使用LEFT JOIN。一致性會讓其他開發人員更容易理解你的SQL。

+3

這是比我在評論中增加一個更好的例子。出於某種原因,我在一個不對稱的簡單操作員上畫空白:-) –

+4

是的。我認爲LEFT的偏好可能來自於開始編寫含有最「重要」表的查詢的自然傾向,這些表通常包含全部信息,即沒有行丟失,並添加可能包含或可能不包含相關信息的表那。 –

4

這些都是平等的,只是偏好和可讀性的問題。我假設它是同一張桌子?

+5

+1,我建議你選擇一個偏好並堅持下去。如果您在外部連接中保持一致,最終結果應該相同。我還建議你使用左外連接,如果你不確定,只是因爲大多數人這樣做。 – Dane

1

這取決於我們的需要 - 我們是否需要左表或右表中的所有列。

兩者都不相同。

+4

在這兩個查詢中,我們得到了Table_1中的所有行..即相同的結果..順便說一句,它應該是..「是否」:) – Vaibhav

2

左外連接

左外連接的結果(或只是左連接)爲表A和B總是包含了「左」表(A)的所有記錄,即使join-條件在「右」表(B)中找不到任何匹配的記錄。這意味着如果ON子句與B中的0(零)記錄相匹配,則連接仍然會在結果中返回一行 - 但B中每列的NULL都爲NULL。這意味着左外部聯接將返回所有來自左表,加(中沒有匹配連接謂詞的情況下或NULL)

右外部匹配右表中的值加入

右外連接(或右連接)非常類似於左外連接,除了表格的處理反轉「右」表(B)中的每一行至少會出現在連接表中一次。如果不存在與「左」表(A)匹配的行,那麼對於那些在B中不匹配的記錄,NULL將出現在來自A的列中。右外連接返回右表中的所有值以及來自左表(在沒有匹配聯接謂詞的情況下爲NULL)。

http://en.wikipedia.org/wiki/Join_%28SQL%29

+2

是的,但我認爲OP問的問題是A LEFT OUTER JOIN B是與B RIGHT OUTER JOIN A相同(注意*表格*與交換方向交換) –

+0

我只是想寫出它們的工作原理,因爲那樣就可以理解它們沒有區別,如果使用它們問題,這是更有用的信息。 –

+0

謝謝@ reader_1000我是這樣解釋:) – Jen

2

SQL語言的設計者正確地認爲,強制從左到右優先聯接將是對語言(可悲的是,他們並沒有感到列順序是一樣的!)不必要的約束

有確實似乎在這裏Stackoverflow上強烈偏好LEFT OUTER,以至於民間人會改變整個連接只是爲了能夠使用LEFT(我們昨天有一個here)。

假定您在查詢Table_2 INNER JOIN Table_1之前最初寫入的內容是在您意識到實際上需要保留Table_1中所有行的外連接之前。將INNER更改爲RIGHT OUTER要比將整個聯接更改爲能夠使用LEFT OUTER要簡單很多。這裏的簡單是很好的,因爲它侵入性較小,因此查詢的意圖被無意中更改的風險較小。

要使用另一個類似的例子,請考慮關係運算符semi join;作爲關係代數的一部分,沒有它的技術不能被認爲是關係完整的。儘管標準SQL確實有一個半連接謂詞MATCH,但它並未廣泛實施。但是,大多數SQL產品都支持各種解決方法。在Stackoverflow上看到的最常見的方法似乎是在SELECT子句中使用INNER JOINDISTINCT,並省略了連接表中的屬性。緊隨其後的是使用WHERE table_1.ID IN (SELECT ID FROM Table_2)。其次最受歡迎的是WHERE EXISTS (SELECT * FROM Table_2 WHERE table_1.ID = table_1.ID)

重點是,以上都是在野外非常常見的半連接。儘管我的個人偏好是使用EXISTS(儘管奇怪的是它更接近關係演算),但我仍然需要能夠將其他人識別爲半連接;有趣的是,最流行的方法(INNER JOINDISTINCT加非投影)可能是最難識別的!

爲了適應個人風格的唯一目的,重構代碼是正確的:不必要的努力的成本,增加風險,源代碼控制的含義等。學會認識和尊重他人的偏好是一項重要技能:如果您發現你自己重構一次只是爲了能夠理解它,你會讓自己處於劣勢。

當然,從關係的角度講,「正確的」答案是完全避免外連接。在關係模型中不存在null這樣的事情,並且外連接被明確地設計爲產生空值。