计算用户平均次日留存率

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

我有一个表,记录用户在网站上的登录信息,包括ID和登录日期。

例如:

id 用户ID 日期
1 1234 2024-01-01
2 2341 2024-01-07
3 2341 2024-01-13
4 3412 2024-01-20
5 4123 2024-01-20
6 4123 2024-01-21
7 4123 2024-01-22
8 2341 2024-01-07
9 2341 2024-01-22
10 3412 2024-01-20
11 4123 2024-01-20
12 4123 2024-01-21
13 4123 2024-01-22
14 2341 2024-01-23
15 2341 2024-01-25
16 3412 2024-01-20

请注意,该表将包含重复数据,因为用户可能每天登录多次。

我现在想计算用户的平均次日留存率,对于上面的示例数据,平均次日留存率为0.3

我尝试了以下查询,但得到的结果是0.4。我觉得我的想法应该是对的,但是不知道为什么结果是错的。

任何人都可以帮我找出问题所在或给我正确的答案吗? (我使用PieCloudDB数据库,如果你没有听说过,可以使用PostgreSQL代替。PieCloudDB与PostgreSQL兼容)

SELECT COUNT(DISTINCT (q2.user_id,q2.date))*1.0/COUNT(DISTINCT (q1.user_id,q1.date)) as avg_ret
from login as q1 
left join login as q2
on q1.user_id=q2.user_id 
and q2.date = q1.date + interval '1 day'
sql postgresql
3个回答
0
投票

我尝试分别对id和日期进行重复数据删除,得到的结果是0.3。 (在pieclouddb数据库云平台测试)

SELECT COUNT(q2.user_id)*1.0 / COUNT(q1.user_id) AS avg_ret
FROM (SELECT DISTINCT user_id, date 
  FROM login) AS q1
LEFT JOIN (SELECT DISTINCT user_id, date 
  FROM login) AS q2
ON q1.user_id = q2.user_id 
AND q2.date = q1.date + interval '1 day'

0
投票

该错误是由

COUNT(DISTINCT q2.user_id, q2.date)
引起的,包括
NULL, NULL
作为不同组合之一。以下查询产生正确的结果 0.3:

SELECT
  COUNT(DISTINCT (q2.user_id, q2.date))
    FILTER (WHERE q2.date IS NOT NULL) * 1.0
  /
 COUNT(DISTINCT (q1.user_id, q1.date)) AS avg_ret
FROM
  login AS q1
  LEFT JOIN login AS q2
    ON q1.user_id = q2.user_id
      AND q2.date = q1.date + INTERVAL '1 day';

0
投票

解决此问题的一个选择是避免

LEFT JOIN
并使用
CASE
EXISTS
逻辑:

WITH login_sub AS
(SELECT
DISTINCT user_id, login_date 
FROM login)
SELECT 
  COUNT(CASE WHEN EXISTS 
    (SELECT 1 FROM login_sub l2 
     WHERE 
       login_sub.user_id = l2.user_id
       AND login_sub.login_date + interval '1 day' = l2.login_date)
  THEN 1 END) * 1.0 / COUNT(*) AS avg_ret
FROM login_sub;  

此查询返回 0.3,请参阅此 样本小提琴 以及您的数据

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