我正在使用SQL Server 2008 R2。这是我的查询,按商店的邮政编码返回每月销售总额。
select
left(a.Zip, 5) as ZipCode,
s.Store,
datename(month,s.MovementDate) as TheMonth,
datepart(year,s.MovementDate) as TheYear,
datepart(mm,s.MovementDate) as MonthNum,
sum(s.Dollars) as Sales,
count(*) as [TxnCount],
count(distinct s.AccountNumber) as NumOfAccounts
from
dbo.DailySales s
inner join
dbo.Accounts a on a.AccountNumber = s.AccountNumber
where
s.SaleType = 3
and s.MovementDate > '1/1/2016'
and isnull(a.Zip, '') <> ''
group by
left(a.Zip, 5),
s.Store,
datename(month, s.MovementDate),
datepart(year, s.MovementDate),
datepart(mm, s.MovementDate)
现在,我想为每个邮政编码和商店添加将销售额,TxnCount和NumOfAccounts与上一年度相比较的列。我还希望每个邮政编码/商店组合都能获得该范围内每个月的记录;如果为null则为零。
我确实有一个日历表,我试图用它来获取所有月份,但由于我的“where”语句,我遇到了问题。
我知道这两个问题(与前一年相比,包括日期范围内的所有日期)之前已经被问过并得到了解答,我已经让他们在我之前工作了,但是这个特别让我参与其中界。任何帮助将不胜感激。
我希望这很清楚。
谢谢, 蒂姆
答案 0 :(得分:0)
将上面的查询视为数据源。在您要报告的期间内将其作为CTE运行,再加上期间 - 12个月(以获取历史数据)。 (SalesPerMonth)
然后执行一个查询,将您需要的所有月份从日历表中作为另一个CTE。这是报告的月份,而不是前一年。 (MonthsToReport)
获取每个有效邮政编码/商店组合的列表 - 可能是与SalesPerMonth CTE不同的选项,这将只为您提供在此期间(或历史期间)至少有一次销售的组合 - 您可能还需要销售的那些去年,但不是今年)。另一个CTE - StoreZip
最后,您的主查询交叉将StoreZip结果与MonthsToReport连接 - 这为您提供了每个StoreZip / Month组合的一行。左连接两次到SalesPerMonth数据,一次为月,一次为1年前的数据。使用ISNULL将任何空记录(无数据)更改为零。
您可以将其作为单独的查询而不是CTE,而是将结果存储在Temp表中。这可能对大量数据更有效。