2014-09-21 210 views
4

我有一個包含1600個唯一項目的表(磨砂)。第二張桌子有100萬加。我跑我的INNER JOIN,並獲得65場比賽:LEFT JOIN返回與INNER JOIN相同的結果

SELECT a.`BW Parent Number` , a.`Vendor Name`, b.`Parent Supplier Name` 
FROM `scrubs` AS a 
JOIN pdwspend AS b ON a.`BW Parent Number` = b.`Child Supplier ID` 
WHERE a.`year` =2014 
AND b.`BU ID` = 'BU_1' 
AND b.version LIKE '%GOV%' 
GROUP BY a.`BW Parent Number` 

然後我運行一個LEFT OUTER JOIN和我一樣,65分的結果:

SELECT a.`BW Parent Number` , a.`Vendor Name`, b.`Parent Supplier Name` 
FROM `scrubs` AS a 
LEFT OUTER JOIN pdwspend AS b ON a.`BW Parent Number` = b.`Child Supplier ID` 
WHERE a.`year` =2014 
AND b.`BU ID` = 'BU_1' 
AND b.version LIKE '%GOV%' 
GROUP BY a.`BW Parent Number` 

爲什麼不從左邊將所有的行表,並顯示與b下不匹配的值爲NULL的值。 Parent Supplier Name

謝謝!

回答

9

因爲您沒有使用on子句。將其更改爲:

SELECT a.`BW Parent Number`, a.`Vendor Name`, b.`Parent Supplier Name` 
    FROM scrubs AS a 
    LEFT OUTER JOIN pdwspend AS b 
    ON a.`BW Parent Number` = b.`Child Supplier ID` 
    and b.`BU ID` = 'BU_1' 
    AND b.`version` LIKE '%GOV%' 
WHERE a.`year` = 2014 

此外,組通過沒有任何意義。如果你正在聚合某些東西,你可以使用group by子句。

根據您對重複行的評論,可能是因爲您稱爲「pdwspend」的表對於每個「子供應商ID」都有多個行。這是您加入「磨砂」桌的唯一場地。所以是的,對於pdwspend上的每一個匹配行,您將擁有與第二個表上的行數相同的行數(該表上可能有其他列,因此它們實際上不是「重複」行,您只是沒有選擇足夠的專欄來說明)。

因爲你只有在選擇數列的興趣,並根據您可以嘗試使用不同的列不想行「重複」:

(你在你把查詢時出現錯誤的原因在你的評論中是因爲你的內聯視圖(你的from子句中的子查詢)沒有選擇'Parent Supplier Name'字段,所以是的,它不存在於內聯視圖中,因爲你沒有將它添加到select內聯視圖列表。

 select a.`BW Parent Number`, a.`Vendor Name`, b.`Parent Supplier Name` 
     from scrubs a 
    left join (select distinct `Child Supplier ID`, `Parent Supplier Name` 
         from pdwspend 
         where `BU ID` = 'BU_1' 
          and `version` LIKE '%GOV') b 
     on a.`BW Parent Number` = b.`Child Supplier ID` 
     where a.`year` = 2014 
+0

會發生什麼情況是,從表pdwspend每個b.'Child供應商ID'可能會出現數百次。當我沒有它時,它會帶來每一場比賽,所以我有很多重複的行。我認爲一個更好的解決方案可能會在這一方面......這也給我一個錯誤!: – nangys 2014-09-21 05:18:20

+0

SELECT a.'BW Parent Number',a.'Vendor Name',b。'父供應商Name' FROM磨砂AS一 LEFT OUTER JOIN( SELECT DISTINCT'兒童供應商ID' FROM pdwspend WHERE'year' = 2014 和'BU ID' = 'BU_1' 和版本LIKE「% GOV%')AS b ON a.'BW Parent Number' = b.'Child Supplier ID' WHERE a.'year' = 2014#1054 - '字段列表'中的未知列'b.Parent Supplier Name' – nangys 2014-09-21 05:20:13

+0

您在'select distinct subquery'內不包含'b.Parent Supplier Name'。重新看Brian的查詢並複製它 – 2014-09-21 23:24:06

7

爲什麼不左表中把所有的行,並表示日NULL那些不匹配的?

您的LEFT JOIN未按預期工作的原因是由於WHERE條款中該表的條件;這有時被稱爲「隱式內部連接」。

這是最好的解釋說明。下面是兩個簡單的表

| USER_ID | FIRST_NAME | LAST_NAME | 
    |---------|------------|------------| 
    |  123 |  Fred | Flintstone | 
    |  456 |  Barney |  Rubble | 

    | ID | USER_ID |  NOTE_BODY | 
    |-------|---------|-----------------| 
    | 98765 |  123 | Yabba Dabba Doo | 

所以如你所料,內連接只產生一個行,其中USER_ID值兩個表中的匹配。

SELECT * FROM用戶üINNER JOIN user_notes N於u.User_ID = ñ。用戶名;

| USER_ID | FIRST_NAME | LAST_NAME | ID |  NOTE_BODY | 
    |---------|------------|------------|-------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 

而且通過改變LEFT JOIN,我們得到的所有記錄中的用戶,但不是所有的都來自User_Notes信息,所以我們得到的NULL這些列

SELECT * FROMüLEFT JOIN用戶 user_notes n ON u.User_ID = n.User_ID;

| USER_ID | FIRST_NAME | LAST_NAME |  ID |  NOTE_BODY | 
    |---------|------------|------------|--------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 
    |  456 |  Barney |  Rubble | (null) |   (null) | 

但是,如果我們真的只是想從連接表的一些記錄會發生什麼?

SELECT * FROM用戶üLEFT JOIN user_notes N於u.User_ID = n.User_ID WHERE n.Note_Body = 'YABBA Dabba鬥';

| USER_ID | FIRST_NAME | LAST_NAME | ID |  NOTE_BODY | 
    |---------|------------|------------|-------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 

那麼,如果我們使用WHERE條件,效果是作爲INNER JOIN一樣,現在我們沒有得到所有用戶的記錄,這是一個隱含的內部聯接

我們沒有得到所有用戶記錄的原因是因爲我們現在堅持所有結果行必須在可能爲NULL的列中具有特定值。所以,我們可以改變WHERE條件來允許NULL。

SELECT * FROM用戶üLEFT JOIN user_notes N於u.User_ID = n.User_ID WHERE(n.Note_Body = 'YABBA Dabba鬥' OR n.Note_Body IS NULL);

| USER_ID | FIRST_NAME | LAST_NAME |  ID |  NOTE_BODY | 
    |---------|------------|------------|--------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 
    |  456 |  Barney |  Rubble | (null) |   (null) | 

OR

而不是使用上,我們增加了加盟條件(ieafter ON)

SELECT * FROM用戶üLEFT JOIN連接表的WHERE子句user_notes n ON u.User_ID = n.User_ID AND n.Note_Body ='Yabba Dabba鬥「;

| USER_ID | FIRST_NAME | LAST_NAME |  ID |  NOTE_BODY | 
    |---------|------------|------------|--------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 
    |  456 |  Barney |  Rubble | (null) |   (null) | 

所以,要小心使用外連接,你的where子句不會覆蓋外連接允許空值。

See the above as a SQLFiddle demonstration

+0

感謝您的回覆!這是非常有用的 – nangys 2014-09-22 00:48:56

+0

沒問題,upvote也表示讚賞(提示) – 2014-09-22 00:49:29

+0

@robsch很好的編輯,謝謝。 – 2016-01-19 10:50:35