我们见过很多关于“连续”概念的问题,比如1、游戏连续签到多少天可以获得奖品;2、计算用户活跃度,连续登陆4天即为活跃等。
这里先给出结论后面进行分析:
要解决的核心问题有:
举例:有一张登录日志记录表,有两列,用户名userId,login_time。一个用户可能有多条记录。问题:怎么找出连续7天登录的用户,是哪7天。
1、分析过程
连续登陆是什么意思,怎么才叫连续,我昨天登陆了,今天登陆了,就连续两天登陆了;我如果明天也会登陆,那么我就连续三天登陆了。这种表现在数据层面是怎么表现的。今天的日期 - 昨天的日期 = 1,说明我连续两天登陆 && 明天的日期 - 昨天的日期=1,说明我连续三天登陆了。那么所有差等于1的行都是连续的(注意第一行要包括)。但是,下一个问题就是,不同的连续登陆区间要怎么区分?
2、提出问题
基于以上分析我们可以认识到:是不是连续的关键就看做差是否一致。但是数据库是不擅长做这种下一行减去上一行的操作的,数据库擅长左边和右边的操作。是不是增加一列呢?
我们怎么样保证不同登陆区间进入不同分组?如果只是等于1,那么不同的登录区间进入一个分组。既然要分组,那么分组的条件是什么?
为了简单,我们简化一下模型。连续问题往往只有两列数据,那用户登录问题来说,一列是:用户名,一列是登录时间(年月日)
3、解决问题
我们拿“用户名”分组,“登录时间”分组,或者“用户名和登录时间“分组都是不合适的,因为他们都不满足我们目的:把**“连续登陆数据”**分到一组来的目的。
关键就是我们的连续数据来源就是:登录时间,登陆时间是增加的,可能连续的,可能不连续的,怎么在可能连续可能不连续的记录中找到共同点,,成了关键问题。。
(增加的,可能连续,可能不连续的)登录时间 + ???? == 固定的数据
从数据中,我们知道,连续增加的数据加上什么数据=不变的数据,必然是连续递增的(0,1,2)的数据,从加减法看,我们可以看成是连续增加的数据。那么是什么呢,row_number出现了。
到这里问题就已经解决了。剩下的大家可以自己思考或者按文章开头给出的结论进行解决。下面是番外(有兴趣的同学可以先尝试吧文章提出的问题解决之后再来看看番外效果更佳)
额外的分析过程。
有两列数据:user_id列,login_time列。
现在有一下问题:求连续登陆超过3天的记录。
下面是解决过程:
连续登陆问题
怎么才叫连续登陆?
我昨天登陆了,我今天也登陆了,我明天也登陆,,,,就是连续登陆(现象)
在数据上游什么表现????(原因)
只能从时间上找“数据原因”
今天日期-昨天日期=1,并且明天日期-今天日期=1(错位相减)
下一行日期-上一行日期=1(数据上)-----------说明连续(现象上)
下一个问题是:
有不同的连续登陆区间(现象)
在数据上就是不同的分组,那么分组的条件是什么
(这个分组条件要保证不同区间的group_id不一样,而且同区间的group_id一样)
找到这个分组的group_Id问题就解决了。
肯定不能是user_id,也不能是login_time,但是只有这两列,,我们可能需要引入第三方列来。
这个列有什么要求:
1、这个列要怎么保证不同连续区间的group_Id不同
2、这个列要怎么保证相同连续区间的group_id相同
只能说根据数学知识,我们知道单调函数每个值,,是不同的
根据物理知识,我们知道相对静止的物体,距离是一样的。
相对静止在这里表现为跟时间变化的差一样--------->等差数列
单调在这里表现为-------->单调递增
等差数列 + 单调递增=========在数据库中用什么表示呢
row_number可以满足这个要求。。
结束!
下面是解题过程:
新增列::::生成单调递增的,等差的row_number,1,2,3,4,5,,,
用时间与新增列做差,如果差一致,说明与时间列相对静止,,又新增列是连续的,所以时间列也是连续的,,又新增列的单调的,,所以不同区间的差是不一样的。
解题完成。