我需要选择每周报告(每个任务类型每周的收入)。对于没有具有某种任务类型的条目的几个星期,我想打印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的任务。
答案 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
您应该使用哪种方式取决于#weeks
和entry
之间的确切关系。如果您的条目没有任何周,并且您希望包含这些条目,那么第一个条目就是好的。如果你不希望任何没有任何周的参赛作品(或者没有周数的参赛作品都不可能),那么第二个参赛作品就是好的。
答案 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 JOIN
与entries
)。
然后IncomePerWeek
计算正确处理条目不存在的COALESCE
NULL
{/ 1}}。