如何计算SQL的生存率?

问题描述 投票:0回答:2

(方言可以是VerticaImpalaDatabricks

我正在尝试计算用户的第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拥有001003004006007 ,其中有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

查询的问题是它从我看的日期起将老玩家删除。例如,使用相同的数据,因为001003004已在2019-11-01上登录,因此2019-11-02的d0值将为2而不是5。因此,仅当我正在寻找新用户时,查询才有效。

我想知道是否可以更改查询以实现我想要的?提前谢谢~~

sql vertica
2个回答
0
投票

这是公认的丑陋方法。想法是标记每个user_id,如果它们是返回日加1,返回日加2等的返回者,然后按login_date进行汇总。希望看到更好的方法。


0
投票

也许有一些自我支持的连接和独特的用户数量?(未经测试)

© www.soinside.com 2019 - 2024. All rights reserved.