天天看点

怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...

在日常业务中,客户行为事件表往往存储的是客户,行为明细,关键字段包括姓名、日期、事件标志等。为考察客户某一行为的连贯性,经常需要查询客户是否存在连续行为,如是否连续登录、连续签到、连续欠息、连续#逾期#等。#SQL#

怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...

在事件表中查询连续行为,涉及到前后多行的复杂判断,直接查询有点困难,需要做一些必要的设计,本文就以判断员工是否连续迟到介绍一种查询方法,其他场景类似。

首先,来看下表结构,包括事件编号、员工姓名、考勤日期、是否迟到标志等四个字段。实际业务中,是否迟到字段可能没有,需要逻辑加工得到,这里简化一下。

怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...
怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...

既然关注的是迟到行为,就先通过late_flag=1筛选出迟到事件,忽略正常事件。既可以使用临时表,也可以使用子查询,本文直接用子查询处理。

对于筛选后的事件,以员工姓名聚合并按考勤日期由小到大排序,得到顺序号row_id,表征客户累计第几次迟到。

select name,curdate#迟到顺序号,row_number() over(partition by name order by curdate asc) as row_idFROM(select * from student_info where late_flag = 1)t1
           
怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...

分析发现,对于某一客户来说,考勤日期和顺序号都是递增的。其中,顺序号是逐个加一递增,日期是按照迟到间隔递增的,如果迟到日期是逐个加一递增,则其与顺序号递增规律一致,不会有跳跃。如果迟到日期是跳跃的,那么其递增的步伐与顺序号不一致。

迟到日期减去顺序号得到的结果恰好可以反映这一情况:连续迟到日期减去对应的顺序号得到是相同的结果,跳跃性日期得到的是不同结果。

select name,curdate,row_id,date_add(curdate,interval -row_id day) as date_delta #获取差值日期FROM(select name,curdate,row_number() over(partition by name order by curdate asc) as row_idFROM(select * from student_info where late_flag = 1)t1)d1
           
怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...

这样就简单了,每一个日期差值代表一次连续迟到行为,按照日期差值进行聚合即可得到不同连续迟到行为的特征,如连续迟到天数、起始日期、结束日期等。

select name,date_delta #按差值日期聚合,min(row_id) as min_row_id,max(row_id) as max_row_id,count(distinct curdate) as late_days #获取迟到天数FROM(select name,curdate,row_id,date_add(curdate,interval -row_id day) as date_deltaFROM(select name,curdate,row_number() over(partition by name order by curdate asc) as row_idFROM(select * from student_info where late_flag = 1)t1)d1)p1group by name,date_delta
           
怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...
select name,date_delta,min_row_id,max_row_id,date_add(date_delta,interval min_row_id day) as late_st_dt #起始日期,date_add(date_delta,interval max_row_id day) as late_end_dt #结束日期FROM(select name,date_delta,min(row_id) as min_row_id,max(row_id) as max_row_id,count(distinct curdate) as late_daysFROM(select name,curdate,row_id,date_add(curdate,interval -row_id day) as date_deltaFROM(select name,curdate,row_number() over(partition by name order by curdate asc) as row_idFROM(select * from student_info where late_flag = 1)t1)d1)p1group by name,date_delta)PP1
           
怎么判断多行数据日期是否连续_「干货」连续行为事件的查询方法与实现(附代码)...

上面就是连续事件的设计和查询方法,其他场景按照类似的方式处理即可。如果您有更好的设计思路,欢迎评论区留言交流。

我是会说科技,关注我,一起聊聊数据、科技、IT、金融那些事。