如何编写简明 sql以按月获取订阅率。
公式:订阅率=订阅次数/试用次数
注意:棘手的部分是,订阅事件应归因于公司开始追踪的月份。
| id | date | type |
|-------|------------|-------|
| 10001 | 2019-01-01 | Trial |
| 10001 | 2019-01-15 | Sub |
| 10002 | 2019-01-20 | Trial |
| 10002 | 2019-02-10 | Sub |
| 10003 | 2019-01-01 | Trial |
| 10004 | 2019-02-10 | Trial |
Based on the above table, the out output should be:
2019-01-01 2/3
2019-02-01 0/1
答案 0 :(得分:2)
一个选项是自联接,以标识每个试验是否最终订阅,然后进行汇总和算术运算:
select
date_trunc('month', t.date) date_month
1.0 * count(s.id) / count(t.id) rate
from mytable t
left join mytable s on s.id = t.id and s.type = 'Sub'
where t.type = 'Trial'
group by date_trunc('month', t.date)
将日期截断到月初的语法在各个数据库中差别很大。以上将在Postgres中工作。其他数据库中也有其他替代方法,例如:
date_format(t.date, '%Y-%m-01') -- MySQL
trunc(t.date, 'mm') -- Oracle
datefromparts(year(t.date), month(t.date), 1) -- SQL Server
答案 1 :(得分:0)
您可以使用窗口功能执行此操作。假设没有重复的试验/订阅:
select date_trunc('month', date) as yyyymm,
count(*) where (num_subs > 0) * 1.0 / count(*)
from (select t.*,
count(*) filter (where type = 'Sub') over (partition by id) as num_subs
from t
) t
where type = 'Trial'
group by yyyymm;
如果id
可以有重复的试验或订阅,那么我建议您问一个新的问题,其中包含有关重复项的更多详细信息。
您也可以通过两个聚合级别来做到这一点:
select trial_date,
count(sub_date) * 1.0 / count(*)
from (select id, min(date) filter (where type = 'trial') as trial_date,
min(date) filter (where type = 'sub') as sub_date
from t
group by id
) id
group by trial_date;