sql计算用户留存率和时间留存率

Sql 29 计算用户的平均次日留存率

题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率。请你取出相应数据。
请添加图片描述

  • 解法1:表里的数据可以看作是全部第一天来刷题了的,那么我们需要构造出第二天来了的字段,因此可以考虑用left join把第二天来了的拼起来,限定第二天来了的可以用date_add(date1, interval 1 day)=date2筛选,并用device_id限定是同一个用户。
-- 通过左连接 筛选出第二天还会来的人
select distinct a.device_id,a.date date1,b.device_id,b.date date2
from question_practice_detail a
left join question_practice_detail b
on a.device_id=b.device_id and date_add(a.date,interval 1 day)=b.date

请添加图片描述

切记 :是左连接

-- 如果没有采用左连接的话
select distinct a.device_id a_device_id,a.date date1,b.device_id b_device_id,b.date date2
from question_practice_detail a,question_practice_detail b
where a.device_id=b.device_id and date_add(a.date,interval 1 day)=b.date

请添加图片描述

-- 通过左连接 筛选出第二天还会来的人
with t as (
select distinct a.device_id a_device_id,a.date date1,b.device_id b_device_id,b.date date2
from question_practice_detail a
left join question_practice_detail b
on a.device_id=b.device_id and date_add(a.date,interval 1 day)=b.date
)
-- 计算用户的次日留存率
select count(date2)/count(date1) avg_ret
from t

请添加图片描述

  • 解法2:用lead函数将同一用户连续两天的记录拼接起来。先按用户分组partition by device_id,再按日期升序排序order by date,再两两拼接(最后一个默认和null拼接),即lead(date) over (partition by device_id order by date)
-- 用lead函数
select avg(if(datediff(date2, date1)=1, 1, 0)) as avg_ret
from (
    select
        distinct device_id,
        date as date1,
        lead(date) over (partition by device_id order by date) as date2
    from (
        select distinct device_id, date
        from question_practice_detail
    ) as a
) as b

sql 计算次日留存率,3日留存率,7日留存率

数据格式如下
在这里插入图片描述

-- 筛选出次留用户
SELECT t1.user_guid,
MAX(CASE WHEN DATEDIFF(date_time,newdate)=1 THEN 1 ELSE 0 END) '是否是次留用户'
FROM(
-- 构建一个每天的新用户表
SELECT user_guid,MIN(date_time) newdate
FROM `view_log`
GROUP BY user_guid
) t1
JOIN view_log t2 ON t1.user_guid=t2.user_guid
GROUP BY t1.user_guid

在这里插入图片描述

SELECT t1.date_time '日期',
COUNT(DISTINCT CASE WHEN DATEDIFF(t3.date_time,t2.newdate)=1 THEN t3.user_guid
ELSE NULL END)/COUNT(DISTINCT t2.`user_guid`) '次日留存率',
COUNT(DISTINCT CASE WHEN DATEDIFF(t3.date_time,t2.newdate)<=3 THEN t3.user_guid
ELSE NULL END)/COUNT(DISTINCT t2.`user_guid`) '3日留存率',
COUNT(DISTINCT CASE WHEN DATEDIFF(t3.date_time,t2.newdate)<=7 THEN t3.user_guid
ELSE NULL END)/COUNT(DISTINCT t2.`user_guid`) '7日留存率'
FROM(
SELECT DISTINCT date_time
FROM view_log
)t1 LEFT JOIN
(SELECT user_guid,MIN(date_time) newdate
FROM view_log
GROUP BY user_guid
)t2 ON t2.newdate=t1.date_timeLEFT JOIN view_log t3 ON t2.user_guid=t3.user_guid
GROUP BY t1.date_time

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/F13122298/article/details/127112159
今日推荐