题解全都用的是left join,对我这个初学者来说有点抽象,用where实现也是可取的。
首先,题目中的日留存率应该对device_id-date的组合进行统计,既要筛出一个设备同一天做多道题的情况,也要包含同一设备不同天做答的情况。 例如只有张三一个用户,他前天做了4道题,昨天做了3道题,今天做了2道题,假设他明天不会做题,那么目前的日留存率就是2/3。
所以总的算式可表示为(满足device_id,date+1在数据表中的distinct device_id, date)/(所有distinct device_id, date)
对于前者,思路为:第一步,计算该条数据的date+1日期;第二步,获得该数据同一个device_id的所有做答日期;第三步,判断date+1是否在第二步所得的做答日期中。因为前两步涉及对同一张表的两次查询,所以将表命名为a,b分别在第一步,第二步中使用,代码如下:
select count(distinct device_id,date)
from question_practice_detail as a #在数据表名后面直接跟字母也同样有效,这里加上as为了表示更清楚
where date_add(date,interval 1 day) in # 获得下一天的日期
#括号中的内容即筛选b表中与a表本条数据id相同的所有做答记录的日期
(select date from question_practice_detail as b
where a.device_id = b.device_id)
对于后者,则只需再次查询即可,合并后的代码如下
select count(distinct device_id,date)
/ (select count(distinct device_id, date) from question_practice_detail)
from question_practice_detail a
where date_add(date,interval 1 day) in (
select date from question_practice_detail b
where a.device_id = b.device_id)