2014-03-31 442 views
3

我有一個帶有「日期」列的表。每行代表一項調查。sql server計算不同年份每月的累計數量

date 
    11/19/2013 5:51:41 PM 
    11/22/2013 1:30:38 PM 
    11/23/2013 3:09:17 PM 
    12/2/2014 5:24:17 PM 
    12/25/2014 11:42:56 AM 
    1/6/2014 2:24:49 PM 

我想統計每月的累計調查次數。從上表可以看出,有2013年11月的3項調查,2013年12月的2項調查,對2014年1月的1項調查。每月調查的累計數量爲:

month | year | number_of_survey 
11 | 2013 | 3 
12 | 2013 | 5 
1  | 2014 | 6 

我有這個疑問這表明調查的正確數量爲2013,與調查的2014號碼是不累積。

with SurveyPerMonth as -- no of Survey per month 
     ( 
     select datepart(month, s.date) as month, 
      datepart(year, s.date) as year, 
      count(*) as no_of_surveys 
     from myTable s 

     group by datepart(year, s.date), datepart(month, s.date) 
     ) 

    select p1.month, p1.year, sum(p2.no_of_surveys) as surveys -- cumulatively 
    from SurveyPerMonth p1 
    inner join SurveyPerMonth p2 on p1.month >= p2.month and p1.year>=p2.year **-- the problem is probably comes from this line of code** 

    group by p1.month, p1.year 
    order by p1.year, p1.month; 

該查詢返回:

month | year | surveys 
11 | 2013 | 3 
12 | 2013 | 5 
1  | 2014 | 1  // 2014 is not cumulative 

如何計算每月調查的累計數2014年呢?

回答

1

像這樣?

SELECT date = create_date INTO #myTable FROM master.sys.objects 

;WITH perMonth ([year], [month], [no_of_surveys]) 
    AS (SELECT DatePart(year, s.date) , 
       DatePart(month, s.date), 
       COUNT(*) 
     FROM #myTable s 
     GROUP BY datepart(year, s.date), 
       datepart(month, s.date)) 
SELECT [year], 
     [month], 
     [no_of_surveys] = (SELECT SUM([no_of_surveys]) 
          FROM perMonth agg 
          WHERE (agg.[year] < pm.[year]) 
           OR (agg.[year] = pm.[year] AND agg.[month] <= pm.[month])) 
    FROM perMonth pm 
ORDER BY [year], [month] 

編輯:看來我錯過了球<>,固定,並添加小例子

+0

如果沒有'CTE',這可能嗎? –

+0

您可以使用'普通'子查詢編寫幾乎每個CTE,例外是遞歸CTE。服務器將CTE和子查詢看成是一樣的,它只是一種不同的語法。 – deroby

0

「 - 這應該幹活已經添加了一個新列‘monthyear’

with surveypermonth as -- no of survey per month 
    ( 
     select datepart(month, s.date) as month, 
     datepart(year, s.date) as year, 
     datepart(year, s.date) *100 + datepart(month, s.date) as monthyear, 
     count(*) as no_of_surveys 
     from test s 
     group by datepart(year, s.date), datepart(month, s.date),datepart(year, s.date)*100 + datepart(month, s.date) 
    ) 

     select a.month,substring(cast(monthyear as varchar(6)),1,4) as year,surveys from 
     (
     select p1.month, p1.monthyear as monthyear, sum(p2.no_of_surveys) as surveys 
     from surveypermonth p1 
     inner join surveypermonth p2 on p1.monthyear>=p2.monthyear 
     group by p1.month, p1.monthyear 
     --order by p1.monthyear, p1.month 
     )a