Home > Software engineering >  find peak logged in time in SQL
find peak logged in time in SQL

Time:07-28

Given User log

userID logintime           logouttime
123    2020/09/03  10:20   2020/09/03  12:30
124    2020/09/03  1:20    2020/09/03  2:30
125    2020/09/03  2:20    2020/09/03  3:30
126    2020/09/03  3:00    2020/09/03  4:30
127    2020/09/03  2:00    2020/09/03  4:30
128    2020/09/03  1:00    2020/09/03  4:30

The goal: Find the peak Logged-in(Active) users in any time? This means that I need to return the timestamp which had the most active session and the number of active sessions in that time stamp. For the above table the result should be:

    timestamp        max
    2020/09/03  2:20  4

as in this timestamp there are 4 active sesion and that is the highest peak.

There is a similar question with Sql Server sql server table peak time but I'm looking to solve this in PostgresSQL

This is what I tried:

Select logintime as time, "login"
from log l1
unoin
Select logouttime as time, "logout"
join log l2
order by time

This should give me 1 ordered time column and now it should be possible to do window count (login 1 and logout -1) then the max number in count column is the most active sessions.

I'm having trouble in implementing this logic in SQL statment

CodePudding user response:

Here it is. The timedata CTE is a mimic of the real user log table.

with timedata (userid, logintime, logouttime) as 
(
 values
 (123, '2020-09-03 10:20'::timestamp, '2020-09-03 12:30'::timestamp),
 (124, '2020-09-03 1:20' , '2020-09-03 2:30' ),
 (125, '2020-09-03 2:20' , '2020-09-03 3:30' ),
 (126, '2020-09-03 3:00' , '2020-09-03 4:30' ),
 (127, '2020-09-03 2:00' , '2020-09-03 4:30' ),
 (128, '2020-09-03 1:00' , '2020-09-03 4:30' )
),
logged_in_count as 
(
 select
   t as point_in_time, 
   (select count(*) from timedata where t between logintime and logouttime) as cnt
 from (select distinct logintime t from timedata) as points_in_time
)
select * from logged_in_count where cnt = (select max(cnt) from logged_in_count);
point_in_time cnt
2020-09-03 02:20:00.000 4
2020-09-03 03:00:00.000 4

In short, make a list of all distinct login times and count how many users are logged for each of them (login_count CTE) and then select the ones with the highest count. No LEAD or LAG are used or re-implemented. You may however use another list of points in time, i.e. generate_series.

  • Related