下面是我们解决问题所需的非常复杂且难以阅读的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
答案 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