• Oracle计算连续天数,计算连续时间,Oracle连续天数统计


    Oracle计算连续天数,计算连续时间,Oracle连续天数统计

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..

    蕃薯耀 2016年11月25日 14:28:00 星期五

    http://fanshuyao.iteye.com/

    mysql计算连续天数,mysql连续登录天数,连续天数统计:

    http://fanshuyao.iteye.com/blog/2341455

    Oracle计算连续天数,计算连续时间,Oracle连续天数统计

    http://fanshuyao.iteye.com/blog/2341163

    今天突然有个想法,就是计算出一个连续时间(天数),表如下:

    create table user_login(
      pid NUMBER not null ,--表示每个用户
      login_time TIMESTAMP not null--登录时间
    );
    
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-25 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-24 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-24 16:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-23 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-23 16:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-21 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-20 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-19 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-18 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-17 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-16 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-15 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-14 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-13 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(1,TO_DATE('2016-11-10 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-25 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-24 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-24 16:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-23 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-22 16:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-21 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-20 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-19 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-18 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-16 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-15 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-14 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(2,TO_DATE('2016-11-13 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    
    insert into user_login(pid, login_time) values(3,TO_DATE('2016-11-24 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(3,TO_DATE('2016-11-23 16:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(3,TO_DATE('2016-11-21 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    
    insert into user_login(pid, login_time) values(4,TO_DATE('2016-11-23 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(4,TO_DATE('2016-11-21 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(4,TO_DATE('2016-11-20 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    
    insert into user_login(pid, login_time) values(5,TO_DATE('2016-11-02 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(5,TO_DATE('2016-11-01 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(5,TO_DATE('2016-10-31 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(5,TO_DATE('2016-10-30 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));
    insert into user_login(pid, login_time) values(5,TO_DATE('2016-10-28 13:30:45', 'yyyy-MM-dd HH24:MI:SS'));

    根据登录时间,算出某个用户的登录连续天数。

    方法一:

    采用递归的方法,如下:

    --根据pid只查询某个人的连续天数  
    --不计算当天的,计算昨天及以前的,所以Sysdate-1
    --想法是把昨天及以前的连续数据查询出来,然后统计记录数
    select count(*) from (
      select * from (
        select distinct pid,TO_DATE(TO_CHAR(LOGIN_TIME, 'YYYY-MM-DD'),'YYYY-MM-DD') LOGIN_TIME from user_login where pid=2
      ) a 
      start with TO_CHAR((Sysdate-1), 'YYYY-MM-DD') = TO_CHAR(a.LOGIN_TIME, 'YYYY-MM-DD') 
      connect by prior TO_CHAR((a.LOGIN_TIME-1), 'YYYY-MM-DD') = TO_CHAR(a.LOGIN_TIME, 'YYYY-MM-DD')
    )
    ; 

    方法二:只适用每个月计算连续天数

    -- 某个人连续时间分段查询(不同的连续时间段),其中row_number()是数据所在的行数,
    --to_number(to_char(d1,'dd'))-row_number() 取当前时间的每月天数减row_number(),只适用于每月的计算
    --如果在不同的月份,算出来就不准,而且row_number()是负数
    --需要理解的是,取当前时间的天数减去当前数据的行数,这是利用一个差相等的思想:
    --由于使用了时间排序,相差一天的数据(必须已经过滤重复)的行数(row_number())相差是1,如果使用当前时间的天数减去行数的差是一样的,证明是连续的,
    --因为当前的时间相差一天,而行数也是相差一,相减之后差就是一样的。
    --如年龄差一样,今年父亲是30岁,儿子是10,相差20,再过20年,他们的年龄差还是20,不会变。
    with t1 as
    (
      select distinct TO_DATE(TO_CHAR(LOGIN_TIME, 'YYYY-MM-DD'),'YYYY-MM-DD') d1 from user_login where pid=5
    )
    select gn,min(d1) start_time,max(d1) end_time,count(*) days
    from(
      select d1,to_number(to_char(d1,'dd'))-row_number() over(order by d1) gn from t1
    )group by gn order by 2 
    ;

    方法三:建议使用这个吧,比较通用,可以跨月使用,可以分段查询,能查询某个时间段内最大的连续天数

    -- 某个人分段查询(不同的连续时间段),其中row_number()是数据所在的行数,
    -- 转换成天数相减,适用于所有的时间段,可以跨月份统计连续天数
    ----select TO_DATE('2016-11-11', 'YYYY-MM-DD')-TO_DATE('1970-01-01', 'YYYY-MM-DD') from dual;--17115--计算天数
    --需要理解的是,取从1970-01-01到现在的天数减去当前数据的行数,这是利用一个差相等的思想:
    --由于使用了时间排序,相差一天的数据(必须已经过滤重复)的行数(row_number())相差是1,使用现在的天数减去行数的差是一样的,证明是连续的,
    --因为天数相差一天,而行数也是相差一,相减之后差就是一样的。
    --如年龄差一样,今年父亲是30岁,儿子是10,相差20,再过20年,他们的年龄差还是20,不会变。
    --这个方法比上面那个方法更加通用,可以跨月份统计连续天数
    with t1 as
    (
      select distinct TO_DATE(TO_CHAR(LOGIN_TIME, 'YYYY-MM-DD'),'YYYY-MM-DD') time_value from user_login where pid=5
    )
    select gn,min(time_value) start_time,max(time_value) end_time,count(*) days
    from(
      select time_value,to_number(time_value-TO_DATE('1970-01-01', 'YYYY-MM-DD'))-row_number() over(order by time_value) gn from t1
    )group by gn order by 2 
    ;

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..

    蕃薯耀 2016年11月25日 14:28:00 星期五

    http://fanshuyao.iteye.com/

  • 相关阅读:
    自动化测试-18.selenium之bugFree代码注释
    自动化测试-16.selenium数据的分离之Excel的使用
    自动化测试-15.selenium单选框与复选框状态判断
    自动化测试-14.selenium加载FireFox配置
    自动化测试-13.selenium执行JS处理滚动条
    Lucas-Kanade算法总结
    迟来的2013年总结及算法工程师/研究员找工作总结
    Android从文件读取图像显示的效率问题
    Viola Jones Face Detector
    谈谈Android中的SurfaceTexture
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/6227091.html
Copyright © 2020-2023  润新知