2013-08-16 202 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天,所以似乎計算邏輯是正確。如果事情不符合預期,請在您的問題中添加實際和期望的輸出。 –