使用 PostgreSQL 计算每日用户的留存率
Calculate retention for daily users with PostgreSQL
我正在尝试使用 pgadminIII / postgresql 计算用户登录会话的每日保留。
table1
有 user_id
、first_login_date
、last_login_date
CREATE TABLE table1 (user_id numeric, first_login_date date, last_login_date date);
INSERT INTO table1 (user_id, first_login_date, last_login_date) VALUES (12346, '2010-06-01', '2010-06-02'),
(67890, '2010-03-01', '2010-03-10'),
(67890, '2010-03-01', '2010-03-10'),
(90123, '2010-08-01', '2010-08-15'),
(45678, '2010-08-01', '2010-08-20'),
(76543, '2010-07-01', '2010-07-01');
table2
有 user_id
、session_id
、login_date
CREATE TABLE table2 (user_id numeric, session_id numeric, login_date date);
INSERT INTO table2 (user_id, session_id, login_date) VALUES
(12346, '8764', '2010-06-02'),
(67890, '4657', '2010-03-05'),
(90123, '3945', '2010-08-09'),
(45678, '20845', '2010-08-02'),
(67890, '29384', '2010-03-07'),
(90123, '3424', '2010-08-12'),
(45678, '349284', '2010-08-10');
table1
中有一些重复项。
因此,我不确定我的查询来计算具有 2 天保留和 5 天保留的用户是否正确。
我在 2 天内使用的查询是:
SELECT table1.user_id, first_login_date, table2.login_date,
(table2.login_date - table1.first_login_date) as datediff, FROM table1
JOIN table2 ON table2.user_id = table2.user_id WHERE
(table2.login_date - table1.first_login_date) = 1;
这给出了 7 位用户保留 2 天的结果
但是,如果我加上distinct子句,比如:
SELECT distinct table1.user_id, first_login_date, table2.login_date,
(table2.login_date - table1.first_login_date) as datediff FROM table1
JOIN table2 ON table2.user_id = table2.user_id WHERE
(table2.login_date - table1.first_login_date) = 1;
我得到了 3 个用户保留 2 天的结果。
我已经咨询了 HERE, HERE and HERE 关于每日留存率的计算,但我不确定我的技术是否给出了正确的结果。例如,要计算 DAU,self-join
会更合适吗?
鉴于 table1
和 table2
中的数据,使用我定义的查询,我的 2 天保留结果是否准确?
是否有优化的方法来计算此留存率?
您正在加入 table2
自身:
ON table2.user_id = table2.user_id
在子查询中执行 distinct
:
select distinct on (t2.login_date)
user_id,
first_login_date,
t2.login_date,
t2.login_date - t1.first_login_date as datediff
from
(
select distinct *
from t1
) t1
inner join
t2 using (user_id)
where t2.login_date - t1.first_login_date = 1
user_id | first_login_date | login_date | datediff
---------+------------------+------------+----------
12346 | 2010-06-01 | 2010-06-02 | 1
45678 | 2010-08-01 | 2010-08-02 | 1
我正在尝试使用 pgadminIII / postgresql 计算用户登录会话的每日保留。
table1
有 user_id
、first_login_date
、last_login_date
CREATE TABLE table1 (user_id numeric, first_login_date date, last_login_date date);
INSERT INTO table1 (user_id, first_login_date, last_login_date) VALUES (12346, '2010-06-01', '2010-06-02'),
(67890, '2010-03-01', '2010-03-10'),
(67890, '2010-03-01', '2010-03-10'),
(90123, '2010-08-01', '2010-08-15'),
(45678, '2010-08-01', '2010-08-20'),
(76543, '2010-07-01', '2010-07-01');
table2
有 user_id
、session_id
、login_date
CREATE TABLE table2 (user_id numeric, session_id numeric, login_date date);
INSERT INTO table2 (user_id, session_id, login_date) VALUES
(12346, '8764', '2010-06-02'),
(67890, '4657', '2010-03-05'),
(90123, '3945', '2010-08-09'),
(45678, '20845', '2010-08-02'),
(67890, '29384', '2010-03-07'),
(90123, '3424', '2010-08-12'),
(45678, '349284', '2010-08-10');
table1
中有一些重复项。
因此,我不确定我的查询来计算具有 2 天保留和 5 天保留的用户是否正确。
我在 2 天内使用的查询是:
SELECT table1.user_id, first_login_date, table2.login_date,
(table2.login_date - table1.first_login_date) as datediff, FROM table1
JOIN table2 ON table2.user_id = table2.user_id WHERE
(table2.login_date - table1.first_login_date) = 1;
这给出了 7 位用户保留 2 天的结果
但是,如果我加上distinct子句,比如:
SELECT distinct table1.user_id, first_login_date, table2.login_date,
(table2.login_date - table1.first_login_date) as datediff FROM table1
JOIN table2 ON table2.user_id = table2.user_id WHERE
(table2.login_date - table1.first_login_date) = 1;
我得到了 3 个用户保留 2 天的结果。
我已经咨询了 HERE, HERE and HERE 关于每日留存率的计算,但我不确定我的技术是否给出了正确的结果。例如,要计算 DAU,self-join
会更合适吗?
鉴于 table1
和 table2
中的数据,使用我定义的查询,我的 2 天保留结果是否准确?
是否有优化的方法来计算此留存率?
您正在加入 table2
自身:
ON table2.user_id = table2.user_id
在子查询中执行 distinct
:
select distinct on (t2.login_date)
user_id,
first_login_date,
t2.login_date,
t2.login_date - t1.first_login_date as datediff
from
(
select distinct *
from t1
) t1
inner join
t2 using (user_id)
where t2.login_date - t1.first_login_date = 1
user_id | first_login_date | login_date | datediff
---------+------------------+------------+----------
12346 | 2010-06-01 | 2010-06-02 | 1
45678 | 2010-08-01 | 2010-08-02 | 1