左连接问题

时间:2011-12-27 02:12:50

标签: mysql sql

我确定这是一个简单的,但我已经看了一个小时,却看不到它。

我在销售/付款系统上有两个表,一个包含不同的付款方式和相关详细信息,另一个包含销售,包括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值,但只会在现金销售发生后出现且有价值。这不是我想要的行为。

任何帮助都会非常感激!

谢谢, 莱恩。

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

WHERE子句中与LEFT JOIN右侧的表相关的任何条件都意味着当没有与JOIN匹配时查询返回0行(因为这些字段不存在)

所以当你说

在哪里

(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;

答案 2 :(得分: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;