2016-12-04 56 views
2

我一直在尋找這個,並試圖使此代碼工作一個星期了。累積計數與組的情況下當

我的數據集tbSubscriptions有列:

Subscription_Date (dd/mm/yyyy hh:mm:ss) 
Subscription_Id (char 6) 
Subscription_Type (char 1) 

要檢索每週訂閱數使用:

select 
    datepart(wk,Subscription_Date) as WeekNo, 
    sum(case when Subscription_Type = 1 then 1 else 0 end) as TotalSubcriptions 
from tbSubscriptions 
group by datepart(wk,Subscription_Date) 
order by 1 

該查詢將返回:

WeekNo |Total Subscriptions 
21  |12 
22  |13 
23  |8 
24  |18 

我想要返回的查詢:

WeekNo |CumulativeSubscriptions 
21  |12 
22  |25 (=12+13) 
23  |33 (=25+8) 
24  |51 (=33+18) 

下面是一個簡單的數據集創建腳本:

GO 
IF OBJECT_ID('tbSubscriptions') IS NOT NULL 
    DROP TABLE tbSubscriptions 
GO 
CREATE TABLE tbSubscriptions (Subscription_Id INT, Subscription_Date datetime, Subscription_Type INT) 
GO 
INSERT INTO tbSubscriptions (Subscription_Id, Subscription_Date, Subscription_Type) 
VALUES 
(1, convert(datetime,'01-08-16 00:00:00 AM',5),1), 
(2, convert(datetime,'15-08-16 00:00:00 AM',5),1), 
(3, convert(datetime,'01-09-16 00:00:00 AM',5),1), 
(4, convert(datetime,'09-09-16 00:00:00 AM',5),1), 
(5, convert(datetime,'18-09-16 00:00:00 AM',5),0), 
(6, convert(datetime,'15-10-16 00:00:00 AM',5),1), 
(7, convert(datetime,'22-10-16 00:00:00 AM',5),0), 
(8, convert(datetime,'23-10-16 00:00:00 AM',5),0), 
(9, convert(datetime,'01-11-16 00:00:00 AM',5),1), 
(10, convert(datetime,'02-11-16 00:00:00 AM',5),1), 
(11, convert(datetime,'14-11-16 00:00:00 AM',5),0), 
(12, convert(datetime,'01-12-16 00:00:00 AM',5),1), 
(13, convert(datetime,'02-12-16 00:00:00 AM',5),1), 
(14, convert(datetime,'05-12-16 00:00:00 AM',5),1), 
(15, convert(datetime,'09-12-16 00:00:00 AM',5),1), 
(16, convert(datetime,'10-12-16 00:00:00 AM',5),1), 
(17, convert(datetime,'11-12-16 00:00:00 AM',5),1), 
(18, convert(datetime,'19-12-16 00:00:00 AM',5),0), 
(19, convert(datetime,'25-12-16 00:00:00 AM',5),0), 
(20, convert(datetime,'29-12-16 00:00:00 AM',5),0); 
GO 

我已經嘗試了累積和兩種方法(窗口功能和自我加盟),但不能去上班。

任何幫助將不勝感激。

親切的問候, 保羅。

+0

它 保護正常工作「SELECT DATEPART(WK,Subscription_Date), ( \t SELECT COUNT(Subscription_Id) \t FROM tbSubscriptions T2 \t WHERE日期部分(WK,t2.Subscription_Date)<=日期部分(WK,t1.Subscription_Date)和 t2.Subscription_Type = 1 )AS running_total FROM tbSubscriptions T1 WHERE \t t1.Subscription_Type = 1 GROUP BY datepart(wk,t1.Subscription_Date) ORDER BY datepart(wk,t1.Subscription_Date)「 –

回答

0

您可以使用CROSS APPLY

with cte as(
    select 
     datepart(wk,Subscription_Date) as WeekNo, 
     sum(case when Subscription_Type = 1 then 1 else 0 end) as TotalSubcriptions 
    from tbSubscriptions 
    group by datepart(wk,Subscription_Date) 
) 
select 
    c.Weekno, 
    t.TotalSubcriptions 
from cte c 
cross apply(
    select sum(TotalSubcriptions) as TotalSubcriptions 
    from cte 
    where WeekNo <= c.WeekNo 
) t 
order by WeekNo 

如果你使用SQL Server 2012及以上版本,您可以使用SUM OVER功能:

with cte as(
    select 
     datepart(wk,Subscription_Date) as WeekNo, 
     sum(case when Subscription_Type = 1 then 1 else 0 end) as TotalSubcriptions 
    from tbSubscriptions 
    group by datepart(wk,Subscription_Date) 
) 
select 
    Weekno, 
    sum(TotalSubcriptions) over(order by WeekNo) as CumulativeSubscriptions 
from cte 
order by WeekNo 
+0

感謝但我正在運行Microsoft SQL Server 2008 R2,它似乎不支持使用OVER運行agregates ORDER BY ...) 更多信息:http://stackoverflow.com/questions/12541355/how-to-use-par按部就班的功能 任何想法? –

+0

@JoãoAlqueres嘗試'CROSS APPLY'解決方案。 –

+0

謝謝菲利克斯!它使用@KthProg的另一種方法在http://stackoverflow.com/questions/860966/calculate-a-running-total-in-sql-server 無論如何謝謝你! –

0

只需使用sum窗口功能。

select distinct 
    datepart(wk,Subscription_Date) as WeekNo, 
    sum(case when Subscription_Type = 1 then 1 else 0 end) 
    over(partition by datepart(wk,Subscription_Date) 
     order by datepart(wk,Subscription_Date)) as TotalSubcriptions 
from tbSubscriptions 
--group by datepart(wk,Subscription_Date) 
order by 1 

編輯:不使用窗口函數,您可以使用相關子查詢。

select datepart(week,subscription_date) wk 
,count(case when subscription_type=1 then 1 end) + 
(select count(case when subscription_type=1 then 1 end) 
from tbsubscriptions t1 
where datepart(week,t.subscription_date)>datepart(week,t1.subscription_date)) cnt 
from tbsubscriptions t 
group by datepart(week,subscription_date) 
+0

謝謝,但我運行Microsoft SQL Server 2008 R2,它似乎不支持與OVER運行agregates(ORDER BY ...) 更多信息:http://stackoverflow.com/questions/12541355/how-to-use-分區和按功能排序的功能 有什麼想法? –

0

的SQL Server 2008版本

with cte as (
    select 
    datepart(year,Subscription_Date) as YearNo, 
    datepart(week,Subscription_Date) as WeekNo, 
    sum(case when Subscription_Type = 1 then 1 else 0 end) as Total 
    from tbSubscriptions 
    group by datepart(year,Subscription_Date), datepart(week,Subscription_Date) 
) 
select 
--t1.YearNo, 
t1.WeekNo, 
sum(t2.Total) as TotalSubcriptions 
from cte t1 
inner join cte t2 on (t1.YearNo*100+t1.WeekNo >= t2.YearNo*100+t2.WeekNo) 
group by t1.YearNo, t1.WeekNo 
order by t1.YearNo, t1.WeekNo; 

SQL Server 2012的版本

select 
--YearNo, 
WeekNo, 
sum(Total) over (order by YearNo, WeekNo) as TotalSubcriptions 
from (
    select 
    datepart(year,Subscription_Date) as YearNo, 
    datepart(week,Subscription_Date) as WeekNo, 
    sum(iif(Subscription_Type = 1,1,0)) as Total 
    from tbSubscriptions 
    group by datepart(year,Subscription_Date), datepart(week,Subscription_Date) 
) q 
order by YearNo, WeekNo; 
+0

謝謝,但我在運行Microsoft SQL Server 2008 R2,它似乎不支持與OVER(ORDER BY ...) 運行agregates更多信息:http://stackoverflow.com/questions/12541355/how-to-use-分區和按功能排序的功能 有什麼想法? –

0

而不是有條件的聚集,如何把Subscription_TypeWHERE

Select Distinct 
     WeekNo   = datepart(wk,Subscription_Date) 
     ,TotalSubcriptions = sum(1) over (Order By datepart(wk,Subscription_Date)) 
From tbSubscriptions 
Where Subscription_Type = 1 
Order By 1 

編輯2008版

;with cte as (
     Select WeekNo=datepart(wk,Subscription_Date) 
      ,Cnt=count(*) 
     From tbSubscriptions 
     Where Subscription_Type = 1 
     Group By datepart(wk,Subscription_Date) 
) 
Select A.WeekNo 
     ,TotalSubcriptions = sum(B.Cnt) 
From cte A 
Join cte B on (A.WeekNo>=B.WeekNo) 
Group By A.WeekNo 
Order By 1 

返回

WeekNo TotalSubcriptions 
32  1 
34  2 
36  3 
37  4 
42  5 
45  7 
49  9 
50  12 
51  13 
+0

謝謝,但我運行Microsoft SQL Server 2008 R2,它似乎不支持與OVER(ORDER BY ...) 運行agregates更多這裏:http://stackoverflow.com/questions/12541355/how-to-use-分區和按功能排序的功能 有什麼想法? –

+0

@JoãoAlqueres不夠公平。僅供參考,當您標記SQL Server時,它通常假定目前支持的版本是2012+。僅供將來參考,請務必提及2008年。 –

+0

@JoãoAlqueres如果仍在尋找更新的答案 –