当前位置 博文首页 > 执剑问道的博客:Oracle中处理连续活跃三天的问题

    执剑问道的博客:Oracle中处理连续活跃三天的问题

    作者:[db:作者] 时间:2021-07-18 10:08

    有道题就是查询当月连续三天活跃的用户,有很多答案,这里说一下一个比较容易理解的。这里先创建一个user1的表:

    create table user1(id number,lg_date date);
    insert into user1 values (11,to_date('2021-01-01','yyyy-mm-dd'));
    insert into user1 values (11,to_date('2021-01-02','yyyy-mm-dd'));
    insert into user1 values(11,to_date('2021-01-04','yyyy-mm-dd'));
    insert into user1 values(11,to_date('2021-01-03','yyyy-mm-dd'));
    insert into user1 values(22,to_date('2021-01-04','yyyy-mm-dd'));
    insert into user1 values (22,to_date('2021-01-07','yyyy-mm-dd'));
    insert into user1 values (22,to_date('2021-01-05','yyyy-mm-dd'));
    insert into user1 values(22,to_date('2021-01-08','yyyy-mm-dd'));
    

    生成的表如图所示:可以看出ID=11和ID=22的用户日期,日期是打乱的。
    在这里插入图片描述

    我们生成一列上移两位的日期列,主要的作用就是,如果连续三天的日期,第一天和第三天相减是2,如果不是连续的,必然大于2。其中,order by lg_date是对日期进行排序。group by id,lg_date的作用是去重相同天数的ID,否则有当天重复的后期相减会报错。这里用到开窗函数:lead(col_name,n) over (partition by…)

    select id,
                    lead(lg_date,2) over(partition by id order by lg_date) "上移日期",
                    lg_date 
              from user1 group by id,lg_date
    

    如图所示:上移日期是在partition by ID下,对日期移动两位。
    在这里插入图片描述
    然后我们在进行日期相减,得出相差天数:

    select s.id, s.lg_date, (s.上移日期 - s.lg_date) df
              from (select id,
                           lead(lg_date,2) over(partition by id order by lg_date) "上移日期",
                           lg_date 
                      from user1 group by id,lg_date) s
    

    如图所示:df为日期差。
    在这里插入图片描述
    此时,只要是df=2,则是有连续三天的日期。例如2021-1-1是被2021-1-3减去为2。最后得出一个全部过程:

    select s1.id, s1.df
      from (select s.id, s.lg_date, (s.上移日期 - s.lg_date) df
              from (select id,
                           lead(lg_date,2) over(partition by id order by lg_date) "上移日期",
                           lg_date 
                      from user1 group by id,lg_date) s ) s1
     group by s1.id, s1.df
    having s1.df = 2;
    

    最后的结果展示:ID为11的符合连续活跃三天的日期。
    在这里插入图片描述
    总结:方法很多,可以参考,主要还是看思路是否清晰,有什么不对的可以指出交流。

    cs