2012-07-04 19 views
4

我知道在這裏創建了許多線程&關於此主題。但是我真的無法得出這兩個陳述之間差異的最後一點!我的意思是,嘗試嘗試我可以達到我所需要的所有結果,但我確實沒有完全控制刀!左和內部加入區別...一次永久

我考慮自己是一個非常優秀的程序員和一個很好的SQL-ISTA,我覺得有點慚愧這個...

下面是一個例子:

  • 我有一個表一個網站的頁面(「網頁」)
  • 一個表與類別(「類別」)。
  • 一個類別可以包含一個或多個頁面,而不是相反
  • 類別可以在所有
  • 不包含頁面的頁面可以是可見或不可見的網站

所以,如果我想顯示所有類別和自己的網頁,我的意思是這兩個類別與頁面,沒有,我必須做這樣的事情:

FROM category 
LEFT JOIN web_page ON (web_page.category_id = category.category_id AND web_page.active = "Y") 

因此,如果該類沒有網頁,我會看到web_page_id NULL的記錄的t帽子類別。

但是,如果我做的:

FROM category 
LEFT JOIN web_page ON (web_page.category_id = category.category_id) 
... 
WHERE web_page.active = "Y"... 

我將只選擇至少有一個web_page類別...但是爲什麼呢?

這只是一個例子......我想永遠理解這種差異!

謝謝。

回答

4

爲了使您的查詢,你打算工作,把狀態進入ON條款:

FROM category 
LEFT JOIN web_page ON web_page.category_id = category 
    and web_page.active = "Y" 

這部作品的原因是(與大多數的數據庫,但不是全部)WHERE子句過濾行後他們加入。如果加入不會導致網頁行加入(因爲該類別沒有網頁),那麼網頁的所有列將爲null,並且任何值(如"Y")與null之間的任何比較都是錯誤的,所以這些非連接的行將被過濾掉。

然而,通過移動狀態進入ON條款,條件執行作爲連接由,這樣你只加入行均active = "Y",但如果沒有任何這樣的行,你我們只需要在左邊加入null網頁。

這個版本的查詢實際上是說:「給我所有的類別及其活躍網頁(如果有的話)」

請注意,我說:「大多數數據庫」 ...例如,mysql足夠聰明,可以理解你正在做什麼,並且你的查詢可以按照你的意圖在mysql上運行。

+0

+1對此答案。謝謝。我總是想知道JOIN或WHERE中的哪一個首先工作。 –

+0

+1非常清楚,完整的答案。謝謝。 –

1

這是因爲SQL正在分階段處理:

  1. FROM條款(所有聯接在此);
  2. WHERE子句;
  3. GROUP BY子句;
  4. 窗口函數(與MySQL無關);
  5. ORDER BY子句。

所以這真的是很重要的,如果你想在web_page.active='Y'過濾或者你想加入相同的條件。在前一種情況下,加入完成後,您只需將結果過濾掉,即可將OUTER加入INNER之一。在後一種情況下,您將獲得所需的結果,因爲不匹配的行將導致相應列的值爲NULL

0

試圖幫助你理解部分。

考慮是SQL語言的一個方面,當在LEFT JOIN中指定條件時,它適用於查找要匹配的記錄。 當條件在底部的WHERE子句中指定時,它適用於所有記錄 - 發生連接之後。如您所見,這會產生意想不到的副作用,即將LEFT JOIN更改爲INNER JOIN

可以解決這個問題做一個WHERE條款是這樣的:

WHERE COALESCE(web_page.active,"Y") = "Y" 

但是,這並不actaully保證的廣告是同樣的結果,這樣做的正確方法是保持在標準JOINON條款。