MySQL当行不存在时返回0

时间:2017-11-30 19:28:57

标签: mysql

下面是我们解决问题所需的非常复杂且难以阅读的SQL语句,我们想知道是否有一种更简单的方法可以做到这一点,我们只是忽略或不知道。

问题:我们正在创建一份报告,该报告需要对特定销售类别的销售数据进行求和,并按类别对其进行分组。问题在于,当其中一个轮班的实例没有在该类别中有任何销售时,它什么也不返回。这对我们不起作用,因为这会导致数据无法正确排列。所以我们需要的是,如果没有实例存在,查询将为移位返回零。我们尝试了左连接,案例陈述,合并,工会等......最终得到的是下面的怪物。关于如何更简单地做到这一点的任何想法将不胜感激。

 SELECT shift_seq,
       amount
FROM   ((SELECT t.shift_seq,
                CASE
                  WHEN EXISTS (SELECT t.shift_seq,
                                      i.amount
                               FROM   a_item AS i,
                                      a_ticket AS t
                               WHERE  i.ticket = t.ticket
                                      AND i.department = 11) THEN
                  Round(Sum(i.amount), 2)
                  ELSE 0.00
                END AS Amount
         FROM   a_ticket AS t
                LEFT JOIN a_item AS i
                       ON i.ticket = t.ticket
         WHERE  i.department = 11
         GROUP  BY t.shift_seq
         ORDER  BY t.shift_seq)
        UNION
        (SELECT t.shift_seq,
                0 AS Amount
         FROM   a_ticket AS t)) AS a
GROUP  BY shift_seq
ORDER  BY shift_seq  

2 个答案:

答案 0 :(得分:0)

对我而言,WHERE i.department = 11条件似乎有效地将您的left join变为inner join,因为该标准适用于右侧表格。这使得整个case表达式变得多余,因为else分支永远不会执行。

老实说,我认为你只需要将上述标准移到连接条件中,然后只需将sum()coalesce()应用于空值:

     SELECT t.shift_seq,
           coalesce(Sum(i.amount),0) AS Amount
     FROM  a_ticket AS t
     LEFT JOIN a_item AS i ON i.ticket = t.ticket AND i.department = 11
     GROUP  BY t.shift_seq

答案 1 :(得分:0)

正如Shadow在上面的评论中指出的那样,更简单的解决方案是将WHERE i.department = 11移动到JOIN子句中。这使我们可以将其缩减为下面的SQL代码,而不是原来的混乱。这导致NULL没有部门的销售,但是在运行它的PHP中很容易处理NULL。再次感谢Shadow。

SELECT t.shift_seq, 
ROUND(SUM(i.amount),2) AS Amount
FROM a_ticket AS t
LEFT JOIN a_item AS i 
ON i.ticket = t.ticket
AND i.department =11
GROUP BY t.shift_seq
ORDER BY t.shift_seq