(方言可以是Vertica
,Impala
或Databricks
)
我正在尝试计算用户的第0天,第1天...直至第7天的生存率。我将某个日期的所有用户都视为d0(无论是新用户还是旧用户),并查看其中有多少人返回d1,d2等。想象一下,我们有以下数据:
user | login_date
-----------------
001 | 2019-11-01
002 | 2019-11-01
003 | 2019-11-01
004 | 2019-11-01
005 | 2019-11-01
001 | 2019-11-02
003 | 2019-11-02
004 | 2019-11-02
006 | 2019-11-02
007 | 2019-11-02
002 | 2019-11-03
003 | 2019-11-03
004 | 2019-11-03
005 | 2019-11-03
008 | 2019-11-03
001 | 2019-11-04
002 | 2019-11-04
006 | 2019-11-04
007 | 2019-11-04
009 | 2019-11-04
而且我想看到这样的东西:
date |d0 |d1 |d2 |d3
--------------------------
2019-11-01| 5 | 3 | 4 | 2
2019-11-02| 5 | 2 | 3 |
2019-11-03| 5 | 1
2019-11-04| 5
因此您可以看到d0为5(即使某些用户之前已经登录),例如,我们在2019-11-02拥有001
,003
,004
,006
,007
,其中有2位在第二天回来。
现在,我开发了一个查询,该查询与我的目标接近,但并不相同。
WITH cte1 AS (
SELECT
user,
login_date,
FIRST_VALUE(login_date) OVER (PARTITION BY user ORDER BY login_date) AS first_login_day,
DATEDIFF(login_date, first_login_day) AS days_since_first_play
FROM
table
)
SELECT
first_login_day,
SUM(CASE WHEN days_since_first_play = 0 THEN 1 ELSE 0 END) AS d0,
SUM(CASE WHEN days_since_first_play = 1 THEN 1 ELSE 0 END) AS d1,
SUM(CASE WHEN days_since_first_play = 2 THEN 1 ELSE 0 END) AS d2,
SUM(CASE WHEN days_since_first_play = 3 THEN 1 ELSE 0 END) AS d3,
SUM(CASE WHEN days_since_first_play = 4 THEN 1 ELSE 0 END) AS d4,
SUM(CASE WHEN days_since_first_play = 5 THEN 1 ELSE 0 END) AS d5,
SUM(CASE WHEN days_since_first_play = 6 THEN 1 ELSE 0 END) AS d6,
SUM(CASE WHEN days_since_first_play = 7 THEN 1 ELSE 0 END) AS d7
FROM
cte1
GROUP BY
first_login_day
ORDER BY
first_login_day
查询的问题是它从我看的日期起将老玩家删除。例如,使用相同的数据,因为001
,003
,004
已在2019-11-01上登录,因此2019-11-02的d0
值将为2而不是5。因此,仅当我正在寻找新用户时,查询才有效。
我想知道是否可以更改查询以实现我想要的?提前谢谢~~
这是公认的丑陋方法。想法是标记每个user_id,如果它们是返回日加1,返回日加2等的返回者,然后按login_date进行汇总。希望看到更好的方法。
也许有一些自我支持的连接和独特的用户数量?(未经测试)