计算 SQL 上给定事件的订户数量
Counting subscriber numbers given events on SQL
我在 mysql 上有一个格式如下的数据集,显示给定某些客户端 ID 的事件历史记录:
Base Data
数据集文本 (subscriber_table):
user_id type created_at
A past_due 2021-03-27 10:15:56
A reactivate 2021-02-06 10:21:35
A past_due 2021-01-27 10:30:41
A new 2020-10-28 18:53:07
A cancel 2020-07-22 9:48:54
A reactivate 2020-07-22 9:48:53
A cancel 2020-07-15 2:53:05
A new 2020-06-20 20:24:18
B reactivate 2020-06-14 10:57:50
B past_due 2020-06-14 10:33:21
B new 2020-06-11 10:21:24
date_table:
full_date
2020-05-01
2020-06-01
2020-07-01
2020-08-01
2020-09-01
2020-10-01
2020-11-01
2020-12-01
2021-01-01
2021-02-01
2021-03-01
我一直在努力想出一个查询来计算给定月份范围内的订阅者数量,事件中没有必要包含这些订阅者数量 table 要么是因为客户仍在订阅,要么是他们取消了,后来又取消了重新订阅。我正在寻找的输出是这样的:
Output
date subscriber_count
2020-05-01 0
2020-06-01 2
2020-07-01 2
2020-08-01 1
2020-09-01 1
2020-10-01 2
2020-11-01 2
2020-12-01 2
2021-01-01 2
2021-02-01 2
2021-03-01 2
重新激活和逾期事件不会更改客户端的订阅状态,但只有取消和新建事件会更改。如果客户在一个月内取消,他们在该月仍应被视为活跃。
我最初的方法是获取每个订户 ID 一个月的最新条目,然后将它们加入预制日期 table,但是当我缺少几个月时,我不确定如何用正确的状态。也许是滞后函数?
with last_record_per_month as (
select
date_trunc('month', created_at)::date order by created_at) as month_year ,
user_id ,
type,
created_at as created_at
from
subscriber_table
where
user_id in ('A', 'B')
order by
created_at desc
), final as (
select
month_year,
created_at,
type
from
last_record_per_month lrpm
right join (
select
date_trunc('month', full_date)::date as month_year
from
date_table
where
full_date between '2020-05-01' and '2021-03-31'
group by
1
order by
1
) dd
on lrpm.created_at = dd.month_year
and num = 1
order by
month_year
)
select
*
from
final
我确实有一个预制的基础 table,其中包含多年中的每个日期都可以用作加入 table
非常感谢任何帮助
谢谢!
这里的方法是将具有新连接的订阅者行作为基础,并使用自连接将它们映射到取消的行。然后以日期 tables 为基础,根据用户数量聚合它们以获得结果。
SELECT full_date, COUNT(DISTINCT user_id) FROM date_tbl
LEFT JOIN(
SELECT new.user_id,new.type,new.created_at created_at_new,
IFNULL(cancel.created_at,CURRENT_DATE) created_at_cancel
FROM subscriber new
LEFT JOIN subscriber cancel
ON new.user_id=cancel.user_id
AND new.type='new' AND cancel.type='cancel'
AND new.created_at<= cancel.created_at
WHERE new.type IN('new'))s
ON DATE_FORMAT(s.created_at_new, '%Y-%m')<=DATE_FORMAT(full_date, '%Y-%m')
AND DATE_FORMAT(s.created_at_cancel, '%Y-%m')>=DATE_FORMAT(full_date, '%Y-%m')
GROUP BY 1
让我分解一些部分
首先,我们需要让订阅者 table 根据 user_id 自行加入,然后离开 table 行 'new' 和右边一个 'cancel' new.type='new' AND cancel.type='cancel'
新的应该总是在取消的行之前所以添加这个new.created_at<= cancel.created_at
因为我们只关心基础table中有new的行,所以我们过滤掉WHERE子句new.type IN('new')
中的行。子查询的结果看起来像这样
然后我们可以用左连接加入这个子查询日期 table 这样 created_at_new 列的年份和月份总是小于等于 full_date DATE_FORMAT(s.created_at_new, '%Y-%m')<=DATE_FORMAT(full_date, '%Y-%m')
但大于取消日期。
最后我们根据 full_date 进行汇总并考虑用户的唯一计数
我在 mysql 上有一个格式如下的数据集,显示给定某些客户端 ID 的事件历史记录: Base Data
数据集文本 (subscriber_table):
user_id type created_at
A past_due 2021-03-27 10:15:56
A reactivate 2021-02-06 10:21:35
A past_due 2021-01-27 10:30:41
A new 2020-10-28 18:53:07
A cancel 2020-07-22 9:48:54
A reactivate 2020-07-22 9:48:53
A cancel 2020-07-15 2:53:05
A new 2020-06-20 20:24:18
B reactivate 2020-06-14 10:57:50
B past_due 2020-06-14 10:33:21
B new 2020-06-11 10:21:24
date_table:
full_date
2020-05-01
2020-06-01
2020-07-01
2020-08-01
2020-09-01
2020-10-01
2020-11-01
2020-12-01
2021-01-01
2021-02-01
2021-03-01
我一直在努力想出一个查询来计算给定月份范围内的订阅者数量,事件中没有必要包含这些订阅者数量 table 要么是因为客户仍在订阅,要么是他们取消了,后来又取消了重新订阅。我正在寻找的输出是这样的:
Output
date subscriber_count
2020-05-01 0
2020-06-01 2
2020-07-01 2
2020-08-01 1
2020-09-01 1
2020-10-01 2
2020-11-01 2
2020-12-01 2
2021-01-01 2
2021-02-01 2
2021-03-01 2
重新激活和逾期事件不会更改客户端的订阅状态,但只有取消和新建事件会更改。如果客户在一个月内取消,他们在该月仍应被视为活跃。
我最初的方法是获取每个订户 ID 一个月的最新条目,然后将它们加入预制日期 table,但是当我缺少几个月时,我不确定如何用正确的状态。也许是滞后函数?
with last_record_per_month as (
select
date_trunc('month', created_at)::date order by created_at) as month_year ,
user_id ,
type,
created_at as created_at
from
subscriber_table
where
user_id in ('A', 'B')
order by
created_at desc
), final as (
select
month_year,
created_at,
type
from
last_record_per_month lrpm
right join (
select
date_trunc('month', full_date)::date as month_year
from
date_table
where
full_date between '2020-05-01' and '2021-03-31'
group by
1
order by
1
) dd
on lrpm.created_at = dd.month_year
and num = 1
order by
month_year
)
select
*
from
final
我确实有一个预制的基础 table,其中包含多年中的每个日期都可以用作加入 table
非常感谢任何帮助
谢谢!
这里的方法是将具有新连接的订阅者行作为基础,并使用自连接将它们映射到取消的行。然后以日期 tables 为基础,根据用户数量聚合它们以获得结果。
SELECT full_date, COUNT(DISTINCT user_id) FROM date_tbl
LEFT JOIN(
SELECT new.user_id,new.type,new.created_at created_at_new,
IFNULL(cancel.created_at,CURRENT_DATE) created_at_cancel
FROM subscriber new
LEFT JOIN subscriber cancel
ON new.user_id=cancel.user_id
AND new.type='new' AND cancel.type='cancel'
AND new.created_at<= cancel.created_at
WHERE new.type IN('new'))s
ON DATE_FORMAT(s.created_at_new, '%Y-%m')<=DATE_FORMAT(full_date, '%Y-%m')
AND DATE_FORMAT(s.created_at_cancel, '%Y-%m')>=DATE_FORMAT(full_date, '%Y-%m')
GROUP BY 1
让我分解一些部分
首先,我们需要让订阅者 table 根据 user_id 自行加入,然后离开 table 行 'new' 和右边一个 'cancel'
new.type='new' AND cancel.type='cancel'
新的应该总是在取消的行之前所以添加这个
new.created_at<= cancel.created_at
因为我们只关心基础table中有new的行,所以我们过滤掉WHERE子句
new.type IN('new')
中的行。子查询的结果看起来像这样然后我们可以用左连接加入这个子查询日期 table 这样 created_at_new 列的年份和月份总是小于等于 full_date
DATE_FORMAT(s.created_at_new, '%Y-%m')<=DATE_FORMAT(full_date, '%Y-%m')
但大于取消日期。最后我们根据 full_date 进行汇总并考虑用户的唯一计数