SQL-如何按天计算活动订户

时间:2020-06-12 13:16:05

标签: mysql sql date count window-functions

以下SQL允许我在手动输入@report_date的指定日期查看活动订阅。相反,我想显示过去两年中活跃用户的图表,因此我希望能够按过去两年中的每一天进行分组。但是,我不确定在过去的每一天如何使@report_date循环。

不幸的是,取消表背后的逻辑令人怀疑。每次客户重新激活其订阅时,取消行都会更新,以将“重新激活”设置为1。如果客户第二次取消,则会在取消表中创建一个新行,并将“重新激活”设置为默认值0。因此,查找在@report_date取消的人,必须将“重新激活”设置为0,或者如果他们已重新激活,则其reactivated_date必须在@report_date之后。

    set @report_date = '2020-06-11';

    SELECT
        @report_date AS Date,
        COUNT(DISTINCT s.customer_id) AS 'Active Subscribers'
    FROM
        subscriptions AS s
    WHERE
        (authorized = 1 OR authorized = 0)
        AND s.created_date < @report_date
        AND s.customer_id NOT IN (SELECT customer_id
                                  FROM cancellations
                                  WHERE (reactivated = 0 OR reactivated_date > @report_date)
                                     AND cancellation_date < @report_date);

订阅表:

customer_id  |  created_date  |  authorized
1               2020-06-06       1
2               2020-06-07       1
3               2020-06-08       -1
4               2020-06-08       1

取消表:

customer_id  |  cancellation_date  |  reactivated  |  reactivation_date
1               2020-06-09            1               2020-06-10
2               2020-06-12            0               NULL
4               2020-06-10            1               2020-06-12

当前输出:

Date        |   Active Subscribers
2020-06-11      1

所需结果:

Date        |   Active Subscribers
2020-06-12        2
2020-06-11        1
2020-06-10        1
etc.

1 个答案:

答案 0 :(得分:0)

假设您的数据一致,则一个选项使用union all,窗口函数和聚合:

select date, sum(is_active = 1) active_subscribers
from (
    select 
        customer_id, 
        date, 
        sum(sum(active_cnt)) over(partition by customer_id order by date) is_active
    from (
        select customer_id, created_date date, 1 active_cnt from subscriptions where autorized in (0, 1)
        union all
        select customer_id, cancellation_date, -1 from cancellations where reactivated = 1
        union all
        select customer_id, reactivation_date, 1 from cancellations where reactivated = 1
    ) t
    group by customer_id, date
) t
group by date
order by date