2013-08-16 206 views
1

我想要遵循类似的示例获取每周和每月总计: StackOverFlow: SQL Add Sum Row for Week and At the End Add the Grand Total。 SQL的这个级别对我来说是一个很大的延伸,所以请尽可能的清楚。SQL添加每周和每月总计

我有一个超过200K记录的ID,Store_ID,Sales_Date,金额的表。

ID Store_ID Amount Sales_Date 
1 215   7 1/29/2012 
2 215   7 1/30/2012 
3 215   7 1/31/2012 
4 215   7 2/1/2012 
5 215   7 2/2/2012 
6 215   7 2/3/2012 
7 215   7 2/4/2012 
8 215   8 2/5/2012 
9 215   8 2/6/2012 
10 215   8 2/7/2012 
    ***More and More Data***   
162 218   4 10/30/2011 
163 218   4 10/31/2011 
164 218   4 11/1/2011 
165 218   4 11/2/2011 
166 218   4 11/3/2011 
167 218   4 11/4/2011 
168 218   4 11/5/2011 
169 218   8 11/6/2011 
170 218   8 11/7/2011 
171 218   8 11/8/2011 
      ******LOTS MORE DATA***** 

我需要生成一个视图,该视图将显示每个Store_ID的每周和每月总计以及总计的关联日期。我遇到的问题是,该示例向我提供了周总数(没有关联日期),月总计(没有关联的日期)和每日金额(这是一项附带收益)。

我需要知道如何在结果中添加额外的列,以显示结束日期和月份结束日期。

这是我迄今(它几乎是完全一样的例子):

set datefirst 7 

select top 100 
    case 
     when grouping(cast(datepart(week, [Sales_Date]) as varchar(255)))=1 then '<MonthEnd>' 
     when grouping(cast([Sales_Date] as date))=1 then '<weektotal>' 
     else cast(cast([Sales_Date] as date) as varchar(255)) 
    end as Period 
    , WkSales = sum(Amount) 
    , Store = Store_ID 
From KF_Store_Sales_Daily 

group by 
    grouping sets( 
    (cast(datepart(month, [Sales_Date]) as varchar(255)), cast(datepart(week, [Sales_Date]) as varchar(255)),cast([Sales_Date] as date)), 
    (cast(datepart(month, [Sales_Date]) as varchar(255)), cast(datepart(week, [Sales_Date]) as varchar(255))), 
    (cast(datepart(month, [Sales_Date]) as varchar(255))) 
    ) 
    , Store_ID 
ORDER BY Store_ID, Sales_Date  

回答

2

下面的查询可以使用每天,每周,每月和每年的总数表明:

select 
    case 
     when grouping(d.m)=1 then 'Year ' + cast(max(d.y) as varchar(10)) 
     when grouping(d.w)=1 then datename(m, max(Sales_Date)) + ' ' + cast(max(d.y) as varchar(10)) 
     when grouping(Sales_Date)=1 then 'Week ' + datename(m, max(ws)) + ' ' + cast(datepart(d, max(ws)) as varchar(20)) + ' - ' 
      + datename(m, max(we)) + ' ' + cast(datepart(d, max(we)) as varchar(20)) 
     else cast(cast([Sales_Date] as date) as varchar(255)) 
    end as Period 
    , Sales = sum(Amount) 
    , Store = Store_ID 
from KF_Store_Sales_Daily 
    cross apply (
     select -- aux. expressions for dates 
      datepart(yy, [Sales_Date]), -- year 
      datepart(m, [Sales_Date]), -- month 
      datepart(wk, [Sales_Date]), -- week 
      dateadd(d, 1-datepart(w, Sales_date), Sales_date), -- week start 
      dateadd(d, 7-datepart(w, Sales_date), Sales_date) -- week end 
    ) d(y, m, w, ws, we) 
group by Store_ID, d.y, rollup (d.m, d.w, Sales_Date) 
order by d.y desc, 
    grouping(d.m), d.m, 
    grouping(d.w), d.w, 
    grouping(Sales_Date), Sales_Date 

我不知道这是多么方便它有蒙太奇和每周总计(因为一周可能属于两个月)。如果您需要分开使用它们,请在两种情况下进行查询。

对每日,每月和每年总计:

select 
    case 
     when grouping(d.m)=1 then 'Year ' + cast(max(d.y) as varchar(10)) 
     when grouping(Sales_Date)=1 then datename(m, max(Sales_Date)) + ' ' + cast(max(d.y) as varchar(10)) 
     else cast(cast([Sales_Date] as date) as varchar(255)) 
    end as Period 
    , Sales = sum(Amount) 
    , Store = Store_ID 
from KF_Store_Sales_Daily 
    cross apply (
     select 
      datepart(yy, [Sales_Date]), 
      datepart(m, [Sales_Date]) 
    ) d(y, m) 
group by Store_ID, d.y, rollup (d.m, Sales_Date) 
order by d.y desc, 
    grouping(d.m), d.m, 
    grouping(Sales_Date), Sales_Date 

对每日,每周和每年的总数(在这种情况下,一个星期可能属于二年):

select 
    case 
     when grouping(d.w)=1 then 'Year ' + cast(max(d.y) as varchar(10)) 
     when grouping(Sales_Date)=1 then 'Week ' + datename(m, max(ws)) + ' ' + cast(datepart(d, max(ws)) as varchar(20)) + ' - ' 
      + datename(m, max(we)) + ' ' + cast(datepart(d, max(we)) as varchar(20)) 
     else cast(cast([Sales_Date] as date) as varchar(255)) 
    end as Period 
    , Sales = sum(Amount) 
    , Store = Store_ID 
from KF_Store_Sales_Daily 
    cross apply (
     select 
      datepart(yy, [Sales_Date]), 
      datepart(wk, [Sales_Date]), 
      dateadd(d, 1-datepart(w, Sales_date), Sales_date), 
      dateadd(d, 7-datepart(w, Sales_date), Sales_date) 
    ) d(y, w, ws, we) 
group by Store_ID, d.y, rollup (d.w, Sales_Date) 
order by d.y desc, 
    grouping(d.w), d.w, 
    grouping(Sales_Date), Sales_Date 
+0

看起来我需要请查看Cross Apply和RollUP,但分解比我预期的要多。我开始认为我需要想出一个更好的方式来获得我需要的东西。我试图通过另一个包含日常数据的Excel重新创建一个Excel报告,该报告链接到这些每周/每年的数字(基于索引匹配公式)。如果我使用这些信息,可能我可以创建一个触发器/函数,每周/每年将其加载到其他表中。我想这也会加快报道速度。意见? –

+0

刚做了一点数学。似乎总数只是星期一到星期六,不包括星期天。善良就像它已经失去了一天(我怀疑)或者将星期一到星期天用作特定的一周。我如何将这个改为周日到周六的一周? –

+0

@BillMannion,我认为它可以减去一周的时间,当它应该总计一个月(或一年),并且该月(或年)在一周结束之前结束。请将缩短的示例查看为SQLFiddle([link](http://sqlfiddle.com/#!3/0e86c/3)),对于周开始为星期一或星期日的两种情况,它总共需要7天,所以似乎计算逻辑是正确。如果事情不符合预期,请在您的问题中添加实际和期望的输出。 –