如何在没有具有特定值的条目的情况下显示总和0?

时间:2015-12-07 14:11:39

标签: sql

我需要选择每周报告(每个任务类型每周的收入)。对于没有具有某种任务类型的条目的几个星期,我想打印0作为收入,但这些组不会出现在我的选择中。 #weeks是临时表,包含我想要报告的所有周数。我应该在查询中修改什么?

SELECT weeks.BeginDate, weeks.EndDate, task.TaskId, task.Abbreviation, task.Name, COALESCE(SUM([entry.Income]), 0) AS IncomePerWeek 
FROM Task task 
LEFT JOIN Entry entry
ON task.TaskId = entry.TaskId 
INNER JOIN #weeks weeks 
ON entry.EntryDate BETWEEN weeks.BeginDate 
AND weeks.EndDate
GROUP BY weeks.BeginDate, weeks.EndDate, task.TaskId, task.Abbreviation, task.Name
ORDER BY weeks.BeginDate, task.Abbreviation

所以我希望结果看起来像这样:

BeginDate    EndDate    TaskId    Abbreviation    Name    IncomePerWeek
----------------------------------------------------------------------
09/11/2015   15/11/2015  1        FT              First   15
09/11/2015   15/11/2015  2        ST              Second  0
...

所以,在2015年11月11日 - 2015年11月15日这一周,在使用TaskId 2的表条目中没有任何条目,但我仍然希望获得该周的行和IncomePerWeek = 0的任务。

2 个答案:

答案 0 :(得分:1)

最简单的解决方案是使用SUM(COALESCE([entry.Income], 0)) AS IncomePerWeek

但是,你的FROM子句对我​​来说不明确。你有一个LEFT JOIN然后立即跟随INNER JOIN到OUTER表。这使得一切都隐含在INNER JOIN中。

根据您的数据,我会使用以下任一项:

FROM Task task 
LEFT JOIN Entry entry
ON task.TaskId = entry.TaskId 
LEFT JOIN #weeks weeks 
ON entry.EntryDate BETWEEN weeks.BeginDate 
AND weeks.EndDate

或者这个:

FROM Task task 
LEFT JOIN (Entry entry
    INNER JOIN #weeks weeks 
    ON entry.EntryDate BETWEEN weeks.BeginDate 
    AND weeks.EndDate)
ON task.TaskId = entry.TaskId

您应该使用哪种方式取决于#weeksentry之间的确切关系。如果您的条目没有任何周,并且您希望包含这些条目,那么第一个条目就是好的。如果你不希望任何没有任何周的参赛作品(或者没有周数的参赛作品都不可能),那么第二个参赛作品就是好的。

答案 1 :(得分:1)

以下作品:

SELECT WT.BeginDate, WT.EndDate, WT.TaskId, WT.Abbreviation, WT.Name, SUM(COALESCE(entries.Income, 0)) AS IncomePerWeek 
    FROM Entry AS entries 
        RIGHT JOIN (
            SELECT weeks.BeginDate, weeks.EndDate, tasks.TaskId, tasks.Abbreviation, tasks.Name
                FROM Task AS tasks, #weeks AS weeks                     
        ) AS WT ON (entries.EntryDate BETWEEN WT.BeginDate AND WT.EndDate) AND WT.TaskId = entries.TaskId 
    GROUP BY WT.BeginDate, WT.EndDate, WT.TaskId, WT.Abbreviation, WT.Name
    ORDER BY WT.BeginDate, WT.Abbreviation

' 要点'是创建的基数 * 任务WT子查询笛卡尔积和 RIGHT JOINentries)。

然后IncomePerWeek计算正确处理条目不存在的COALESCE NULL {/ 1}}。