【问题标题】:SQL Retention RatesSQL 保留率
【发布时间】:2021-06-03 23:09:21
【问题描述】:

我正在尝试构建一个滚动保留度量,但在弄清楚如何在 redshift 中执行它时遇到了麻烦。

我将留存定义为两组用户之间的交集。第一个是一组不同的用户 ID,从今天起 90 天内至少在该日期起 30 天内(从今天起 90 到 120 天)活跃过一次。第二个是从今天起过去 30 天内活跃的用户数。

留存率 = 90 天前原始队列中的今天 30 天活跃用户 / 90 天前 30 天活跃用户

我的会话表如下所示:

id created_date
1 2021-03-04
1 2021-01-01
1 2020-12-15
2 2021-02-17

我似乎可以这样做的唯一方法如下:

  1. 创建一个寺庙表并插入今天的日期。
with t1 as (
    select distinct customer_id id
    from sessions
    and created_date >= dateadd('day', -29, current_date)
    )
, t2 as (
    select distinct customer_id id
    from sessions
    and created_date <= dateadd('day', -89, current_date) 
    and created_date >= dateadd('day', -119, current_date)
    )
select current_date, 
    count(t1.id) as original, 
    count(t2.id) as current,
    round(cast(count(t2.id) as float) / cast(count(t1.id) as float), 2) as ratio
into temp table temp1
from t1
left join t2
on t1.id = t2.id
  1. 在临时表中多次运行插入语句,每次查询从当前日期减去一天
insert into temp1
with t1 as (
    select distinct customer_id id
    from sessions 
    and created_date >= dateadd('day', -29, current_date-1)
    )
, t2 as (
    select distinct customer_id id
    from sessions
    and created_date <= dateadd('day', -89, current_date-1) 
    and created_date >= dateadd('day', -119, current_date-1)
    )
select current_date-1,  
    count(t1.id) as original, 
    count(t2.id) as current,
    round(cast(count(t2.id) as float) / cast(count(t1.id) as float), 2) as ratio
from t1
left join t2
on t1.id = t2.id
  1. 获取此表,其中包含 2021 年迄今为止所有日期的每日保留率

原始列是自参考日期起 90 天前 30 天活跃用户的用户群组。 当前列是原始列中同类群组中在参考日期为 30 天活跃用户的用户数。

第 1 步仅返回第一行 2021-03-05,第 2 步返回另一行。

date original current ratio
2021-03-05 100 70 0.7
2021-03-04 100 60 0.6

这个过程显然效率很低,我想知道是否有更快、更简单的方法来做到这一点?问题是我需要比较 3 个月前的不同用户群组,然后看看今天有多少来自群组的用户仍然活跃。

我们将不胜感激!

【问题讨论】:

  • 我不关注这个问题。这都是关于“今天的日期”,但你也在谈论历史日期。然后是这样的声明:“从今天开始的 90 位,在过去 30 天内至少活跃过一次”。 90 天还是 30 天?
  • 嗨,戈登,在今天(2021 年 3 月 5 日),我需要查看过去 90 天的数据,并找出当时(2020 年 12 月 6 日)30 天活跃用户的数量那个日期。假设那个日期有 100 个,然后我想知道该队列中有多少在今天是 30 天活跃的。假设有 70 个,所以 70%。我对此有一个有效的查询,但我也需要昨天和当天。基本上需要每天重复去年的计算。
  • 这有帮助吗?

标签: sql amazon-redshift


【解决方案1】:

如果要获取每个日期今天30天和90天前的用户数,查询为:

with t1 as (
  select
    s2.created_date,
    count(distinct customer_id id) as cnt30
  from sessions s1 inner join
    (select distinct created_date from sessions) s2
    on dateadd('day', -29, s2.created_date)<=s1.created_date
       and s1.created_date<=s2.created_date
  group by s2.created_date
)
select a1.current_date, 
  a1.cnt30 as original, 
  a2.cnt32 as current,
  round(cast(a2.cnt30) as float) / cast(count(a1.cnt30) as float), 2) as ratio
from t1 as a1 inner join t1 as a2
  on dateadd('day', -89, a1.created_date)=a2.created_date
order by 1

使用选择列表中的子查询,查询是:

with t1 as (
  select
    s2.created_date,
    (select count(distinct s1.customer_id) from sessions s1
     where dateadd('day', -29, s2.created_date)<=s1.created_date
       and s1.created_date<=s2.created_date) as cnt30
  from
    (select distinct created_date from sessions) s2
)
select a1.current_date, 
  a1.cnt30 as original, 
  a2.cnt32 as current,
  round(cast(a2.cnt30) as float) / cast(count(a1.cnt30) as float), 2) as ratio
from t1 as a1 inner join t1 as a2
  on dateadd('day', -89, a1.created_date)=a2.created_date
order by 1

首先,使用联接和子查询计算每个日期过去 30 天的唯一 ID 数。 接下来,加入相同的表并输出当天和 90 天前的唯一 ID 数。

请注意,我从未使用过 redshift,所以我将根据您的查询和常见的 SQL 语法编写此内容。希望我的回答对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多