2012-02-17 16 views
3

隨着LEFT JOINMysql(左)JOIN如何解釋這種行爲?

SET @foo:=0; 
SELECT @foo 
FROM test t1 
    LEFT JOIN test t2 ON t2.id=t1.id AND (@foo:[email protected]+1); 

打印0,0,0,0,0,0,0 ......

但JOIN

SET @foo:=0; 
SELECT @foo 
FROM test t1 
    JOIN test t2 ON t2.id=t1.id AND (@foo:[email protected]+1); 

打印1,2, 3,4,5,6 ...

有人知道嗎?謝謝!

UPD。此查詢產生相同的行除了@foo值

+0

你有沒有比較的兩個'EXPLAIN SELECT's?我不知道這有幫助,但http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/ – biziclop 2012-02-17 08:39:04

+1

這本身就是一個有趣的問題。但是你可以通過SELECT @foo:= @ foo + 1來解決這個問題。 – Mchl 2012-02-17 08:59:55

回答

1

會話變量的賦值在ON子句中不起作用。

你看到@foo遞增INNER JOIN的原因在於優化運行查詢爲:

SET @foo:=0; 
SELECT @foo 
FROM test t1 
    JOIN test t2 
    WHERE t2.id=t1.id AND (@foo:[email protected]+1); 

使用EXPLAIN SELECT...你應該額外欄中看到using where

您也可以使用EXPLAIN EXTENDED SELECT...然後SHOW WARNINGS來查看優化器如何運行您的查詢。

在你的情況下,LEFT JOIN查詢完全按照它的寫法運行,對於這種類型的加入,你可以在ONWHERE的相同條件下得到不同的結果。

如果你想增加@foo爲LEFT JOIN使用:

SET @foo:=0; 
SELECT @foo 
FROM test t1 
    LEFT JOIN test t2 ON t2.id=t1.id 
    WHERE @foo:[email protected]+1 
0

也許,如果第一個返回false MySQL的引擎不檢查第二個條件,順序是可能的LEFT JOIN

+0

這可以只適用於OR惰性條件,但不適用於AND。因爲在兩個操作符必須計算,以找出結果 – zim32 2012-02-17 08:36:22

+0

另外我會假設測試表是相同的兩個例子。 – 2012-02-17 08:41:05

+0

Ups。我是小白)你是對的),並且如果左運算符爲FALSE,則可以跳過正確的計算 – zim32 2012-02-17 08:41:39

0

你提到,選擇一些額外的數據從你的表t1?
這兩個操作之間的區別可能是左連接的行爲。按照規則嘗試加入LEFT JOIN。它從左側的數據集中選擇一條記錄,並嘗試右鍵加入數據集中的其他數據。如果沒有匹配,則右側數據集的所有列都將設置爲NULL並加入。正常JOIN跳過記錄不可以JOIN的地方。

id 
-- 
1 
2 
3 
4 

LEFT JOIN選取記錄a,嘗試LEFT JOIN其他記錄。每個ID不像ID的記錄都會導致失敗JOIN。但是,由於所需的左側數據(記錄a)可用,所以LEFT JOIN不會跳過這些記錄。因此,結果記錄填充了連接記錄的NULL,並且foo不會遞增。

+0

添加其他數據會得到相同的結果。例如SELECT *,@foo會產生相同的結果。 – zim32 2012-02-17 09:08:27

+0

另一個有趣的事情是,除了@foo值,這兩個查詢產生相同的結果) – zim32 2012-02-17 09:19:30

相關問題