Reputation: 328
I am trying to calculate subscription churn. I have a table that looks like the following:
subid | startdate | enddate
000001 | 9/26/2016 | 10/26/2016
000002 | 11/4/2015 | 12/4/2016
000003 | 11/18/2016| 12/18/2016
000004 | 8/3/2016 | 10/16/2016
000005 | 7/16/2016 | 11/29/2016
To calculate churn by month I need to create logic that looks like the following:
select
date_trunc('month',enddate) as month,
count(id), --of all accounts with an enddate of that month
count(id), --of all accounts that have a start date prior to that month and an end date equal to or after that month
from table1
Essentially the goal here is to find the number of subscriptions ending on a given month and also count the number of subscriptions that are still active during that month. I have no idea how to do this within the same group since the second count(id) is conditional to the first.
The result of the example table rows would be this:
date | count1 | count2
10/1/2016 | 2 | 4
11/1/2016 | 1 | 3
12/1/2016 | 2 | 3
Upvotes: 2
Views: 62
Reputation: 49270
You can use correlated sub-queries to get the different counts.
select distinct
date_trunc('month',enddate) as mnth,
(select count(*) from table1
where date_trunc('month',enddate) = date_trunc('month',t1.enddate)) count1,
(select count(*) from table1
where date_trunc('month',enddate) >= date_trunc('month',t1.enddate)
and date_trunc('month',startdate) <= date_trunc('month',t1.enddate)) count2
from table1 t1
order by 1
Another way is to self-join.
select
date_trunc('month',t1.enddate) as mnth,
count(distinct t1.subid) c1,
count(distinct t2.subid) c2
from table1 t1
left join table1 t2 on date_trunc('month',t2.enddate)>= date_trunc('month',t1.enddate) and date_trunc('month',t2.startdate)<= date_trunc('month',t1.enddate)
group by date_trunc('month',t1.enddate)
order by 1
Upvotes: 2