2016-12-04 3 views
2

Ich habe dies gesucht und versucht, diesen Code für eine Woche arbeiten zu lassen.Kumulative Zählung mit Gruppe von und Fall, wenn

Meine Datensatz tbSubscriptions die Spalten:

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

Um die Anzahl der Abonnements pro Woche abrufen Ich benutze:

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 

Diese Abfrage liefert:

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

Was ich want ist eine Abfrage, die zurückgibt:

Hier ist ein Beispiel Datensatzerstellung Skript:

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 

ich beiden Methoden für die kumulative Summe versucht habe (Window-Funktionen und Selbst Joins), konnte aber nicht an der Arbeit.

Jede Hilfe würde sehr geschätzt werden.

Mit freundlichen Grüßen, Paulo.

+0

IT arbeitete mit „ Datumsteil SELECT (wk, Subscription_Date), ( \t SELECT Count (subscription_id) \t FROM tbSubscriptions t2 \t WHERE Datumsteil (wk, t2.Subscription_Date) <= Datumsteil (wk, t1.Subscription_Date) und t2.Subscription_Type = 1 ) AS running_total FROM tbSubscriptions t1 WHERE \t t1.Subscription_Type = 1 GROUP BY datenteil (wk, t1.Subscription_Date) ORDER BY datenteil (wk, t1.Subscription_Date) " –

Antwort

0

können Sie CROSS APPLY verwenden:

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 

Wenn Sie SQL Server 2012 verwenden und oben können Sie auch die SUM OVER Funktion:

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

Vielen Dank, aber ich laufe Microsoft SQL Server 2008 R2 und es scheint nicht laufen Agregates mit OVER (ORDER BY ...) Mehr hier: http://stackoverflow.com/questions/12541355/how-to-use-par nach-und-Reihenfolge-in-über-Funktion Irgendwelche Gedanken? –

+0

@ JoãoAlqueres Versuchen Sie die 'CROSS APPLY' Lösung. –

+0

Danke Felix! Es funktionierte mit einer anderen Methode von @KthProg bei http://stackoverflow.com/questions/860966/calculate-a-running-total-in-sql-server Vielen Dank trotzdem! –

0

Verwenden Sie einfach die sum Fensterfunktion.

Bearbeiten: Ohne Fensterfunktionen zu verwenden, können Sie eine korrelierte Unterabfrage verwenden.

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

Danke, aber ich laufe Microsoft SQL Server 2008 R2 und es scheint nicht zu laufen aggregates mit OVER (ORDER BY ...) Mehr hier: http://stackoverflow.com/questions/12541355/how-to-use- Partition-by-and-Order-by-in-over-Funktion Irgendwelche Gedanken? –

0

SQL Server 2008-Version

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-Version

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

Vielen Dank, aber ich laufen Microsoft SQL Server 2008 R2 und es scheint nicht zu laufen aggregates mit OVER (ORDER BY ...) Mehr hier: http://stackoverflow.com/questions/12541355/how-to-use- Partition-by-and-Order-by-in-over-Funktion Irgendwelche Gedanken? –

0

Anstatt die bedingte Aggregation, wie etwa Subscription_Type im WHERE

setzen
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 

bearbeiten Version 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 

Returns

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

Danke, aber ich laufen Microsoft SQL Server 2008 R2 und es scheint nicht zu laufen aggregates mit OVER (ORDER BY ...) Mehr hier: http://stackoverflow.com/questions/12541355/how-to-use- Partition-by-and-Order-by-in-over-Funktion Irgendwelche Gedanken? –

+0

@ JoãoAlqueres Fair genug. Zu Ihrer Information: Wenn Sie SQL Server taggen, wird im Allgemeinen von derzeit unterstützten Versionen ausgegangen, die 2012+ sind. Nur für zukünftige Referenz, nur darauf achten, 2008 zu erwähnen. –

+0

@ JoãoAlqueres Siehe aktualisierte Antwort, wenn Sie noch suchen –