[英]What's the simplest way to make a SQL query to generate cumulative subscribers?
I have a subscriptions
table (in postgresql) with the columns subscribed_at
and unsubscribed_at
.我有一个subscriptions
表(在 postgresql 中),其中包含subscribed_at
和unsubscribed_at
列。 I'd like to write a simple query that produces a list of the cumulative subscriber count (subscribed minus unsubscribed as of that date) for each month end.我想编写一个简单的查询,生成每个月末的累积订阅者计数列表(订阅减去截至该日期的未订阅)。
Each row is essentially querying: if the group_by month is "January-2020" how many subscriptions have subscribed_at
date with a month on or before January 2020, and a unsubscribed_at
date of null or after January 2020.每一行本质上是在查询:如果 group_by 月份是“2020 年 1 月”,有多少订阅subscribed_at
日期为 2020 年 1 月或之前的一个月,而unsubscribed_at
日期为 null 或 2020 年 1 月之后。
I'm just not familiar enough with SQL to know the right syntax here.我只是对 SQL 不够熟悉,无法在这里了解正确的语法。
Any help would be much appreciated!任何帮助将非常感激!
Table桌子
+----+------+---------------+-----------------+
| id | name | subscribed_at | unsubscribed_at |
+----+------+---------------+-----------------+
| 1 | John | '2020-01-08' | null |
| 2 | Mary | '2020-01-09' | '2020-01-20' |
| 3 | Jeff | '2020-01-10' | null |
| 4 | Bill | '2020-02-02' | null |
| 5 | Bob | '2020-02-08 | '2020-02-21' |
+----+------+---------------+-----------------+
Query询问
SELECT DATE_TRUNC('month', subscribed_at) as month,
COUNT(*) as subscribers
FROM subscriptions
GROUP BY 1
ORDER BY 1
Desired Output所需 Output
+---------------+-------------+
| month | subscribers |
+---------------+-------------+
| January 2020 | 2 |
| February 2020 | 3 |
+---------------+-------------+
Where subscribers
is the cumulative net subscribers at the end of that month.其中, subscribers
是当月末的累计净订阅者。
Here is a SQLFiddle with the data and query: http://www.sqlfiddle.com/#!15/cd7725/1这是一个带有数据和查询的SQLFiddle:http://www.sqlfiddle.com/#!15/cd7725/1
You could use generate_series()
to enumerate all months between the first subscription start and the latest subscription end, and then a lateral join to compute the active subscriptions count.您可以使用generate_series()
枚举第一次订阅开始和最新订阅结束之间的所有月份,然后使用横向连接来计算活动订阅数。
select d.dt, n.no_active_subscriptions
from (
select generate_series(
date_trunc('month', min(subscribed_at)),
date_trunc('month', max(unsubsribed_at)),
interval '1 month'
) dt
from subscriptions
) d
cross join lateral (
select count(*) no_active_subscriptions
from subscriptions s
where
s.subscribed_at < d.dt + interval '1 month'
and (s.unsubscribed_at >= d.dt or s.unsubscribed_at is null)
) n
Here is an approach.这是一种方法。 Calculate +1 on the date someone starts and -1 on the date the stop.在某人开始的日期计算 +1,在停止的日期计算 -1。 Then do a cumulative sum.然后做一个累积和。
For the end of the month, take the last record per month:对于月末,取每个月的最后一条记录:
with s as (
select dte, sum(inc) ondate, sum(sum(inc)) over (order by dte) as subs
from subscriptions s cross join lateral
(values (subscribed_at, 1), (unsubscribed_at, -1)
) v(dte, inc)
where v.dte is not null
group by v.dte
)
select distinct on (date_trunc('month', dte)) *
from s
order by date_trunc('month', dte), dte desc;
Here is a db<>fiddle.这是一个 db<>fiddle。
This may be exactly what you want.这可能正是您想要的。 . . . . or you might want to tweak it.或者你可能想要调整它。
(date_trunc('month', dte) + interval '1 month - 1 day')::date
.如果您想报告该月的最后一天,您可以使用表达式(date_trunc('month', dte) + interval '1 month - 1 day')::date
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.