I have a table in Oracle that tracks user login and logout/timeout. I am making a select query to show me the concurrent users by hour for the past 7 days. I have a base query, but it does not properly count users who's session crosses midnight.
Bit of information on the data/my query:
- Logintracking holds all user login actions such as login/logout/timeout actions. Each action is on a separate row.
Attemptdate
is when the action took placeAttemptresult7
is the result of the login action (LOGIN/LOGOUT/TIMEOUT)Maxsessionuid
is the users session id, which can be used to link the login with the logout/timeout.- I'm using a left outer self join to match up logins with logouts based on the session id. Since the user may still be logged in I replace null logout dates with sysdate.
- I group data by year/month/day and remove any records where the user might have logged in twice with a distinct. The same user logged in 10 times is only considered 1 concurrent user in this report. (This part isn't really working either, as my distinct is on both login and logout hour, which would probably be different between sessions. I really need to combine overlapping sessions for the same user...)
- I count the number of concurrent users by seeing if each hour from 0 to 23 is between their login and logout (which of course won't work for sessions that cross days)
--My Oracle Query so far:
Select Lyear,
Lmonth,
Lday,
Sum(Case When 0 Between Lhour And Ohour Then 1 Else 0 End) H00,
Sum(CASE WHEN 1 between LHour and OHour Then 1 Else 0 End) H01,
Sum(CASE WHEN 2 between LHour and OHour Then 1 Else 0 End) H02,
Sum(Case When 3 Between Lhour And Ohour Then 1 Else 0 End) H03,
Sum(CASE WHEN 4 between LHour and OHour Then 1 Else 0 End) H04,
Sum(CASE WHEN 5 between LHour and OHour Then 1 Else 0 End) H05,
Sum(CASE WHEN 6 between LHour and OHour Then 1 Else 0 End) H06,
Sum(CASE WHEN 7 between LHour and OHour Then 1 Else 0 End) H07,
Sum(CASE WHEN 8 between LHour and OHour Then 1 Else 0 End) H08,
Sum(Case When 9 Between Lhour And Ohour Then 1 Else 0 End) H09,
Sum(CASE WHEN 10 between LHour and OHour Then 1 Else 0 End) H10,
Sum(CASE WHEN 11 between LHour and OHour Then 1 Else 0 End) H11,
Sum(CASE WHEN 12 between LHour and OHour Then 1 Else 0 End) H12,
Sum(CASE WHEN 13 between LHour and OHour Then 1 Else 0 End) H13,
Sum(CASE WHEN 14 between LHour and OHour Then 1 Else 0 End) H14,
Sum(CASE WHEN 15 between LHour and OHour Then 1 Else 0 End) H15,
Sum(Case When 16 Between Lhour And Ohour Then 1 Else 0 End) H16,
Sum(Case When 17 Between Lhour And Ohour Then 1 Else 0 End) H17,
Sum(Case When 18 Between Lhour And Ohour Then 1 Else 0 End) H18,
Sum(CASE WHEN 19 between LHour and OHour Then 1 Else 0 End) H19,
Sum(Case When 20 Between Lhour And Ohour Then 1 Else 0 End) H20,
Sum(Case When 21 Between Lhour And Ohour Then 1 Else 0 End) H21,
Sum(CASE WHEN 22 between LHour and OHour Then 1 Else 0 End) H22,
Sum(Case When 23 Between Lhour And Ohour Then 1 Else 0 End) H23
From (
Select Distinct L1.Userid,
Extract(Year From L1.Attemptdate) Lyear,
Extract(Month From L1.Attemptdate) Lmonth,
Extract(Day From L1.Attemptdate) Lday,
--You can't extract HOUR from a date, must be a timestamp
Extract(Hour From Cast(L1.Attemptdate As Timestamp)) As Lhour,
Extract(Hour From Cast(NVL(L2.Attemptdate,SYSDATE) As Timestamp)) As OHour
From Maximo.Logintracking L1
LEFT OUTER JOIN Maximo.Logintracking L2 On
L1.Maxsessionuid = L2.Maxsessionuid
Where L1.Attemptresult7 = 'LOGIN' And L2.Attemptresult7 != 'LOGIN'
And L1.Attemptdate > Trunc( Sysdate)-7
And L2.Attemptdate > Trunc(Sysdate)-7) Sessions
Group By Lyear, Lmonth, Lday
ORDER By LYear, LMonth, LDay
The query doesn't have to stay anything like it is now. But the end result should be that I have a x day view of concurrent users by hour.
Related: How to count the number of concurrent users using time interval data?