我先给出我自己的写法,这个方法比较笨拙。第一步:在原表的结构上,虚拟出四列,其中分别是:当前行的logon_date的下一天,当前行的logon_date的下两天,当前行的往后推一行的logon_date,当前行的往后推两行的logon_date,sql如下所示:
select
t.user_id,
t.user_name,
t.logon_date,
t.logon_date+1 as next_1day_date,
t.logon_date+2 as next_2days_date,
lead(t.logon_date, 1, null) over(partition by t.user_id order by t.logon_date) as next_1row_date,
lead(t.logon_date, 2, null) over(partition by t.user_id order by t.logon_date) as next_2row2_date
from
user_logon_history t
order by t.user_id, t.logon_date
第二步:对上述的结果进行过滤,得到符合条件的记录,筛选过滤的条件是:上图中红色的列相等,并且蓝色的列也相等。sql语句如下:
select a.* from (
select
t.user_id,
t.user_name,
t.logon_date,
t.logon_date+1 as next_1day_date,
t.logon_date+2 as next_2days_date,
lead(t.logon_date, 1, null) over(partition by t.user_id order by t.logon_date) as next_1row_date,
lead(t.logon_date, 2, null) over(partition by t.user_id order by t.logon_date) as next_2row2_date
from
user_logon_history t
order by t.user_id, t.logon_date
) a where a.next_1day_date = a.next_1row_date
and a.next_2days_date = next_2row2_date
第三部就是再包装一层查询,统计出最后的结果,sql语句如下:
select f.user_id,
f.user_name,
count(f.logon_date)
from (
select a.* from (
select
t.user_id,
t.user_name,
t.logon_date,
t.logon_date+1 as next_1day_date,
t.logon_date+2 as next_2days_date,
lead(t.logon_date, 1, null) over(partition by t.user_id order by t.logon_date) as next_1row_date,
lead(t.logon_date, 2, null) over(partition by t.user_id order by t.logon_date) as next_2row2_date
from
user_logon_history t
order by t.user_id, t.logon_date
) a where a.next_1day_date = a.next_1row_date
and a.next_2days_date = next_2row2_date
) f group by f.user_id,f.user_name
having count(f.logon_date) >= 1;