【问题标题】:SQL monthly subscription rateSQL 包月费率
【发布时间】:2020-11-07 19:17:36
【问题描述】:

如何写一个简洁的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

【问题讨论】:

  • 日期函数是高度特定于供应商的。请用您正在使用的数据库标记您的问题:mysql、oracle、sql-server...?

标签: sql date count


【解决方案1】:

一个选项是自联接,以确定每个试验是否最终订阅,然后是聚合和算术:

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

【讨论】:

    【解决方案2】:

    您可以使用窗口函数来做到这一点。假设没有重复的试用/订阅:

    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;
    

    【讨论】:

      猜你喜欢
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 2020-08-25
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多