需求描述
客户找我计算同时在线人数峰值,并列出用户登陆时间和退出时间,数据库仅有一张用户登录日志表可供使用,不得已,便分解需求:
- 创建表在线人数峰时表 ,用在存放每个时间段内同时在线人数;
- 在线人数峰时表 ,循环插入数据,避免数据量过大,每次只插入超过当前峰值人数的数据,并删除小于当前峰值的数据,便可始终保留一条;
- 查询在线人数峰时表,便可了解何时登录人数最高;
- 查询该时间段前登录时间和后退出时间的登录信息即可;
有类似需要的同学可使用该方法,例如:利用入院时间及出院时间,计算同时住院患者峰值;
可利用部分
代码片
第一步:建表
--第一步:建表,(日期,当日峰值)
create table TEST_PEAK
(
p_begin_time DATE,
cnt NUMBER
)
tablespace TEST_SPACE
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 16K
next 8K
minextents 1
maxextents unlimited
);
comment on table TEST_PEAK
is '同时在线峰值';
comment on column TEST_PEAK.p_begin_time
is '时间';
comment on column TEST_PEAK.cnt
is '峰值:同时在线人数';
第二步:插入数据
--第二步:插数据, (日期,当日峰值)
declare
P_BEGIN_TIME date := to_date( '20200101','YYYY/MM/DD') ;--初始日期
begin
loop
insert into TEST_PEAK
(P_BEGIN_TIME, CNT)
select P_BEGIN_TIME, count(1)
from t_login_log l
where P_BEGIN_TIME between l.login_time and l.loginout_time
group by P_BEGIN_TIME
having count(1) > (select nvl(max(t.cnt), 0) from TEST_PEAK t);
delete from TEST_PEAK t
where t.cnt < (select nvl(max(t.cnt), 0) from TEST_PEAK t);
commit;
P_BEGIN_TIME := P_BEGIN_TIME + 1 / 24;
exit when trunc(P_BEGIN_TIME) = trunc(sysdate) ; --结束日期
end loop;
end;
/
第三步:查询
select * from TEST_PEAK ;
显而易见,在2021/9/6 18:00:00同时在线用户数最多,达到142名用户;
延伸
例如:利用入院时间及出院时间,计算同时住院患者峰值;
可在第二bu步 17行,将
P_BEGIN_TIME := P_BEGIN_TIME + 1 / 24,改为
P_BEGIN_TIME := P_BEGIN_TIME + 1 ;
P_BEGIN_TIME := P_BEGIN_TIME + 1 ; --循环递增一天
P_BEGIN_TIME := P_BEGIN_TIME + 1 / 24 ; --循环递增一小时
P_BEGIN_TIME := P_BEGIN_TIME + 1 / (24*60) ; --循环递增一分钟