累积计数与组的情况下当

问题描述:

我一直在寻找这个,并试图使此代码工作一个星期了。累积计数与组的情况下当

我的数据集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)

您可以使用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 无论如何谢谢你! –

只需使用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-分区和按功能排序的功能 有什么想法? –

的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-分区和按功能排序的功能 有什么想法? –

而不是有条件的聚集,如何把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如果仍在寻找更新的答案 –