2008-12-16 221 views
10

這是Mysql的表連接中的「using」和「on」有什麼區別?

... T1 join T2 using(ID) where T2.VALUE=42 ... 

一樣

... T1 join T2 on(T1.ID=T2.ID) where T2.VALUE=42 ... 

所有類型的連接?

我對using(ID)的理解是,它只是on(T1.ID=T2.ID)的簡寫。這是真的?


現在另一個問題:

就是上面一樣

... T1 join T2 on(T1.ID=T2.ID and T2.VALUE=42) ... 

這我不認爲是真實的,但爲什麼呢? on子句中的條件如何與連接進行交互,以及它在where子句中如何進行交互?

+0

只是出於興趣你使用的數據庫是什麼?我只是嘗試了SQL Server上的USING語法,它似乎不起作用。 – 2008-12-16 16:13:36

+0

我正在使用MySQL – Pyrolistical 2008-12-16 17:47:05

回答

12

我不使用using語法,因爲

  1. 我的大部分的連接並不適合它(不是被匹配的相同的字段名,和/或多個匹配的連接)和
  2. 它不是立即明顯它轉化爲與兩個以上的表

即假設有「身份證」和「ID_2」列3代表的情況下,確實

T1 JOIN T2 USING(id) JOIN T3 USING(id_2) 

成爲

T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T1.id_2=T3.id_2 AND T2.id_2=T3.id_2) 

T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T2.id_2=T3.id_2) 

還是其他什麼東西來着?

對於某個特定的數據庫版本來說,這是一個相當簡單的練習,但我沒有很大的信心認爲它在所有數據庫中都是一致的,並且我不是唯一一個必須維護我的代碼(所以其他人也必須知道它相當於什麼)。

與其中Vs上的明顯的區別是如果連接是外:

假定T1與單個ID字段,包含值1,並用ID和值字段一個T2一行(一個行,ID = 1,VALUE = 6),則我們得到:

SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID) WHERE T2.VALUE=42 

沒有給出的行中,由於在需要進行匹配,而

SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID AND T2.VALUE=42) 

會給一行與所述值

1, NULL, NULL 

由於ON僅用於匹配連接,因爲連接是可選的,因爲它是外部連接。列

1

您的解釋看起來正確。 This article可能會有所幫助。

至於第二個問題,我看不出爲什麼你的第三個例子的結果應該與前兩個的結果不同。 「ON」子句中的任何條件與在「WHERE」子句中具有相同的含義。

+1

不,根據ON子句中的連接類型條件可能與where子句具有非常不同的含義。 – 2008-12-16 02:24:57

1

我相信你是正確的 - USING(xx)是加入兩個具有相同名稱的列的簡稱。

至於第二個問題,兩個查詢可能是是相同的或可能是不同的,具體取決於特定於數據庫的查詢計劃程序實現。爲了找出你自己(至少在postgres中)做一個EXPLAIN SELECT ...來看看如何執行查詢計劃。

1

如果只有一個連接,則沒有區別。

使用條款的缺點是兩個表必須具有相同的列名稱。

5

USING子句是簡寫等值連接,假設由同名兩個表中存在的列:

A JOIN B USING (column1) 

A JOIN B ON A.column1=B.column1 

您也可以命名多個列,這使得加入的複合按鍵相當直截了當。下面加入應該是等價的:

A JOIN B USING (column1, column2) 

A JOIN B ON A.column1=B.column1 AND A.column2=B.column2 

注意USING (<columnlist>)需要有括號,而ON <expr>是不是有括號(雖然括號可圍繞<expr>任何其他可用於周圍的表達只是它們可以被包含需要上下文)。

此外,沒有其他表加入查詢可能有一個由該名稱的列,否則查詢是不明確的,你應該得到一個錯誤。

關於您對附加條件的疑問,假設您使用INNER JOIN,它應從邏輯上給出與查詢相同的結果,但優化計劃可能會受到影響,具體取決於RDBMS實施。如果在連接中包含條件,則OUTER JOIN也會給出不同的結果,而WHERE子句中包含條件。

0

你在這裏得到了答案,我不需要添加到它。一旦我對此進行了性能測試,並且始終如一地使用並始終以比ON更快的速度運行。是的,我正在談論10到20毫秒:) MySQL我正在談論

0

結果有差別,我沒有在其他答案中看到。如果你這樣做:

JOIN ... ON t1.common = t2.common 

那麼結果集將有兩列名爲common,特別是t1.commont2.common,因爲它是不明確的不合格的名字將不會在查詢工作。

如果,另一方面,你這樣做:

JOIN ... USING (common) 

那麼結果集將只有一個名爲common一列,而這將是一個不合格的名稱 - 既不t1.common也不t2.common將出席會議。

相關問題