2015-11-05 55 views
1

我有兩個表。 A和項目,(庫存主列表) B帶項目,日期和銷售(片)MYSQL左連接函數結果缺失行

我:

cursor.execute(
    "SELECT A.item, sum(B.qty) \ 
    FROM A \ 
    LEFT JOIN sales on A.item = B.item \ 
    WHERE B.date BETWEEN %s AND %s\ 
    GROUP BY A.item", (gr2014start, gr2014end)) 

這並不列出一個 據我所知,所有項目在選定日期範圍內,A中的某些項目在B上沒有任何銷售,因此它不存在。 有沒有辦法可以將它們列爲零與連接功能?

我有這樣的:

cursor.execute("SELECT A.item, \ 
    (SELECT COALESCE(sum(qty),0) From B \ 
    WHERE (A.item = B.item) \ 
    AND (B.date BETWEEN %s AND %s)) as 'Qty' \ 
    FROM A", (gr2014start, gr2014end)) 

這工作。但不知怎的,這個很慢(比頂部的不完整連接功能慢3或4倍)

謝謝。

回答

3

當您使用LEFT JOIN,如果沒有匹配的行表B,那些列將是NULL,所以B.date BETWEEN %s AND %s將永遠是錯誤的。

B.date的限制放在ON子句中,而不是WHERE子句:LEFT JOIN sales AS B ON A.item = B.item AND B.date BETWEEN %s AND %s。這是ON子句只應包含要連接的表之間的比較的一般規則的例外。

+0

我擊敗@Barmar來回答! ...但你的更好... –

+0

謝謝@Barmar。不知何故1)在這種情況下不起作用,可能是因爲a中的某些項不存在於b中。與1)它仍然不會返回與A相同長度的完整列表。2)完美地工作 – viviwill

+0

1)應該同樣如此。你在WHERE子句中有沒有在問題中顯示的附加測試?確保你在'OR'表達式周圍放置了圓括號。 – Barmar

0

由於您正在做left join,因此B中的某些日期將爲NULL。如果你想在日期範圍內的所有結果,並與B中沒有相關記錄的結果,你需要考慮的是:

WHERE B.date IS NULL OR B.date BETWEEN %s AND %s 
+0

請參閱我的答案下面的評論。如果所有匹配的行都在日期範圍之外,這將不起作用。 – Barmar