2010-04-27 66 views
34

下面的語句產生相同的結果(一個正在使用on,和其他使用where):在SQL/MySQL中,連接語句中的「ON」和「WHERE」有什麼區別?

mysql> select * from gifts INNER JOIN sentGifts ON gifts.giftID = sentGifts.giftID; 
mysql> select * from gifts INNER JOIN sentGifts WHERE gifts.giftID = sentGifts.giftID; 

我可以在左外的情況下,只看到加入尋找「無與倫比」的情況:
(找出從未被任何人發來的禮物)

mysql> select name from gifts LEFT OUTER JOIN sentgifts 
      ON gifts.giftID = sentgifts.giftID 
      WHERE sentgifts.giftID IS NULL; 

在這種情況下,首先使用on,然後whereon是否先進行匹配,然後where進行「次要」過濾?還是有更一般的規則使用onwhere?謝謝。

+0

非常相似http://stackoverflow.com/questions/2559194/difference-between-and-and-where-in-joins – 2010-04-27 16:08:36

+1

這個問題有兩個更好的標題。 – ripper234 2010-08-30 20:08:22

回答

38

WHERE是作爲整體的SELECT查詢的一部分,ON是每個單獨連接的一部分。

ON只能引用先前使用的表的字段。

當與左表中的記錄沒有實際匹配時,LEFT JOIN從右表返回一條記錄,所有字段均設置爲NULLSWHERE子句然後評估並過濾此。

在您的查詢中,只返回gifts中'sendgifts'不匹配的記錄。

這裏的例子

gifts 

1 Teddy bear 
2 Flowers 

sentgifts 

1 Alice 
1 Bob 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 

--- 

1 Teddy bear 1  Alice 
1 Teddy bear 1  Bob 
2 Flowers  NULL NULL -- no match in sentgifts 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 
WHERE sg.giftID IS NULL 

--- 

2 Flowers  NULL NULL -- no match in sentgifts 

正如你所看到的,沒有實際的比賽能留在sentgifts.id一個NULL,所以只有那些沒有曾經被送到返回的禮物。

0

如果您正在使用JOIN,則需要指定要加入的條件。該列表位於ON子句中。 WHERE子句用於爲查詢中的任何位置調整數據。

2

雖然結果相同,但'ON'首先使聯接,然後檢索聯接的集合的數據。檢索速度更快,負載更少。但是使用'WHERE'會導致首先獲取兩個結果集,然後應用該條件。所以你知道什麼是首選。

11

當使用INNER JOIN時,ONWHERE將具有相同的結果。所以,

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
where t1.Name = 'John' 

會有完全相同的輸出

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
    and t1.Name = 'John' 

正如你所提到的,使用OUTER JOIN當這種情況並非如此。構建哪個查詢計劃取決於數據庫平臺以及查詢細節,並且可能會發生變化,因此僅憑這個基礎做出決策並不能提供有保證的查詢計劃。

作爲一個經驗法則,您應該使用ON子句和列用於在WHERE子句中進行過濾的表格。這提供了最佳的可讀性。

+0

使用「ON」與比field1 = field2更復雜的東西是否正確? – skan 2013-08-29 17:31:08

+0

是的,通常有多列ON子句。 – RedFilter 2013-08-29 17:36:11

+0

我的意思是,除了列比較之外,你還可以使用複雜的表達式嗎? – skan 2013-08-29 22:04:03

40

ON子句定義了表之間的關係。

WHERE條款描述你是哪個行感興趣。

很多時候,你可以交換他們仍然得到同樣的結果,但是這並不總是與左外連接的情況。

  • 如果ON子句失敗,您仍會得到一行左列中的列,但右列中的列中有空值。
  • 如果WHERE子句失敗,則根本無法獲得該行。
+0

Upvote for the last two statements – Sekai 2018-01-15 15:44:45

相關問題