2011-12-27 88 views
0

我敢肯定這是一個容易的,但我一直在看它一個小時,只是看不到它。問題與左連接

我在銷售/支付系統上有兩張表,一張包含不同的付款方式和相關詳細信息,另一張包含銷售額,包括ID,總計和付款方式。

在期末,我想調出所有不同方法的總數,如果沒有,則爲NULL或0。

這是查詢我:

SELECT m.method_id, m.description, SUM(s.total) as total 
FROM payment_method m 
     LEFT JOIN sale s ON s.payment_method = m.method_id 
WHERE m.for_stock_keeping = 0 AND 
(s.shift_id = ? OR s.shift_id IS NULL) 
GROUP BY m.method_id; 

,直到我們開始一個新的ID的另一個轉變它工作正常,那麼已經在先前的轉變中使用任何付款方式不再如果沒有銷售露面針對該方法而發生。 即:如果我做10次現金銷售這個轉變,然後開始一個新的轉移現金將不會再顯示一個NULL值,但只會出現在現金出售後,並且有一個值。這不是我想要的行爲。

任何幫助將非常感謝!

謝謝, 瑞恩。

回答

1

WHERE子句中s.shift_id的條件應用在外連接之後;你之前需要應用它。

你有兩個選擇(至少):

SELECT m.method_id, m.description, SUM(s.total) as total 
    FROM payment_method m 
    LEFT JOIN sale s ON s.payment_method = m.method_id AND 
         (s.shift_id = ? OR s.shift_id IS NULL) 
WHERE m.for_stock_keeping = 0 
GROUP BY m.method_id, m.description; 

和:

SELECT m.method_id, m.description, SUM(s.total) as total 
    FROM payment_method m 
    LEFT JOIN (SELECT * FROM Sale AS a WHERE a.shift_id = ? OR a.shift_id IS NULL) AS s 
    ON s.payment_method = m.method_id 
WHERE m.for_stock_keeping = 0 
GROUP BY m.method_id, m.description; 
+0

兩者都很完美。不能相信我沒有看到......謝謝! – itsreeyan 2011-12-27 02:35:34

0

該查詢看起來不錯,但也許你的DBMS很關心m.method_id既不是聚合函數也不是group by子句。試試這個:

SELECT m.method_id, m.description, SUM(s.total) as total 
FROM payment_method m LEFT JOIN sale s ON s.payment_method = m.method_id 
WHERE m.for_stock_keeping = 0 AND (s.shift_id = ? OR s.shift_id IS NULL) 
GROUP BY m.method_id, m.description; 
+0

感謝您的回覆,但這並不能解決問題。 – itsreeyan 2011-12-27 02:35:54

+0

分組問題是MySQL以外的DBMS的問題。 MySQL或多或少的工作 - 特別是在這種情況下,一個分組列('m.method_id')是主鍵,以便其他非聚合列在功能上依賴於GROUP BY列。 – 2011-12-27 02:37:51

1

任何條件在WHERE,涉及到該表在左右側子句JOIN是怎麼回事意思是查詢在沒有匹配JOIN時返回0行(因爲那些字段不存在)

所以當你說

WHERE

(s.shift_id = ? OR s.shift_id IS NULL) 

沒有從s行中沒有支付一個新的轉變來檢查,所以這個標準總是會失敗。

所以,只要移動檢查到JOIN,你會沒事的。

SELECT m.method_id, m.description, SUM(s.total) as total 
FROM payment_method m 
     LEFT JOIN sale s ON s.payment_method = m.method_id AND (s.shift_id = ? OR s.shift_id IS NULL) 
WHERE m.for_stock_keeping = 0 
GROUP BY m.method_id;