Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Is any operator logged in between times? how long?

Author  Topic 

AskSQLTeam
Ask SQLTeam Question

0 Posts

Posted - 2002-01-17 : 11:06:17
Ivanner writes "This is a tricky problem. I have a table named tblLoginLogout with 3 fields: Operator, LoginTime and LogoutTime. Let's say I have OperatorA logged in at 12:05:15 AM and logged out at 8:03:34 AM, OperatorB logged in at 8:05:15 AM and logged out at 4:03:34 PM, OperatorC logged in at 4:00:00 PM and logged out at 12:03:34 AM. I need to create a report where shows the following information:

12:00:00 AM - 12:59:59 AM
How long was at least one operator logged in? (Should return 54:45 mins or 3285 seconds)
...
...
8:00:00 - 8:59:59 AM
How long was at least one operator logged in? (Should return 58:19 mins or 3499 seconds)

9:00:00 AM - 9:59:59 AM
How long was at least one operator logged in? (Should return 60 mins or 3600 seconds)
...
4:00:00 PM - 5:59:59 PM
How long was at least one operator logged in? (Should return 60 mins or 3600 seconds, Note that two accounts overlap times)
...
11:00:00 PM- 11:59:59 PM

And I need to accoplish the same report in 24 hours intervals.
Example
01/01/2002 00:00:00 - 01/01/2002 23:59:59
01/02/2002 00:00:00 - 01/02/2002 23:59:59
...

Any Ideas on how to acomplish that? Please let me know if there is (or not) a way to do it.
Thanks a lot for your help."

chadmat
The Chadinator

1974 Posts

Posted - 2002-01-17 : 12:51:27
I think you could do it, but you might need to capture the DATE part of the datetime.

Then you could write a SELECT CASE query the does a sum of datediffs (The arguments would change depending on the case).

I started to write it for you, but then realized I would need the date because 12:03:34 AM is less than 4:00 PM without the date, but 12:03:34 AM 1/17/02 is greater than 4:00 PM 1/16/02.

HTH
-Chad

Go to Top of Page

Ivanner
Starting Member

2 Posts

Posted - 2002-01-17 : 16:19:24
You are right, I forgot to mention it. The field is DateTime so it holds the time AND the date. I still can't figure out how to accomplish the query.
Any help will be appreciated.

Go to Top of Page

Arnold Fribble
Yak-finder General

1961 Posts

Posted - 2002-01-17 : 18:55:13
This isn't very efficient, but I think it does what you want. You might want to check for fencepost errors on the interactions between the logins and logouts and the reporting periods.


DECLARE @RepStartTime datetime, @RepEndTime datetime, @RepFreq int


SET @RepStartTime = '2001-01-01 00:00:00'
SET @RepEndTime = '2002-01-01 00:00:00'
SET @RepFreq = 3600


SELECT HStart,
@RepFreq - SUM(
CASE WHEN InTime IS NULL THEN
0
ELSE
DATEDIFF(second,
CASE WHEN OutTime > HStart THEN OutTime ELSE HStart END,
CASE WHEN InTime < HEnd THEN InTime ELSE HEnd END)
END
)
FROM (
SELECT HStart, DATEADD(second, @RepFreq, HStart) HEnd
FROM (
SELECT DATEADD(second, N * @RepFreq, @RepStartTime) HStart
FROM Numbers
WHERE N * @RepFreq < DATEDIFF(second, @RepStartTime, @RepEndTime)
) a
) hours
LEFT JOIN (
SELECT OutTime, InTime
FROM (
SELECT T1.LogoutTime OutTime, MIN(T2.LoginTime) InTime
FROM tblLoginLogout AS T1, tblLoginLogout AS T2
WHERE T1.LogoutTime < T2.LoginTime
GROUP BY T1.LogoutTime) a
WHERE NOT EXISTS (
SELECT 1 FROM tblLoginLogout
WHERE LoginTime < InTime AND LogoutTime > OutTime)
) lapses ON HStart < InTime AND HEnd > OutTime
GROUP BY HStart
ORDER BY HStart

Where Numbers is a single-column (N) table of non-negative integers (...hmm, deja vu) with at least as many rows as reporting periods (365*24 = 8760, here).

The subquery hours just generates a row for each contiguous period being reported (from @RepStartTime to @RepEndTime in @RepFreq second periods). It should really be called something else. I wouldn't recommend changing @RepFreq to much less than 3600!

The subquery lapses find the periods when no operator was logged in. It isn't very efficient, but it should be ok for 8 hour shifts of 3 operators and it will cope with the general case. For each logout time, it finds the next login time and checks there are no (other) operator sessions overlapping that logout-to-login period.

The main query just joins each lapse to the hours it occurs in and calculates the period for each lapse that falls within the hour, then groups by hours and adds all the lapses in the hour (this is ok because lapses can't overlap by definition).

This was 'tested' (for small values of 'tested') on a table like this:

CREATE TABLE tblLoginLogout (
Operator int NOT NULL,
LoginTime datetime NOT NULL,
LogoutTime datetime NOT NULL)

with test data for 3 operators working 8 hours shifts, logging in and out up to 1/2 hour either side of their nominal time:

SET NOCOUNT ON
DECLARE @o int, @shiftstart datetime
DECLARE @start datetime, @end datetime


SET @shiftstart = '2001-01-01 00:00:00'

WHILE @shiftstart < '2002-01-01 00:00:00'
BEGIN
SET @o = 0
WHILE @o < 3
BEGIN
SET @start = DATEADD(second, FLOOR(RAND() * 3600.0 - 1800.0), @shiftstart)
SET @shiftstart = DATEADD(hour, 8, @shiftstart)
SET @end = DATEADD(second, FLOOR(RAND() * 3600.0 - 1800.0), @shiftstart)
INSERT INTO tblLoginLogout VALUES (@o, @start, @end)
SET @o = @o + 1
END
END
SET NOCOUNT OFF




Edited by - Arnold Fribble on 01/18/2002 04:26:08
Go to Top of Page

Arnold Fribble
Yak-finder General

1961 Posts

Posted - 2002-01-18 : 12:31:08
To follow up Ivanner's email question about creating a table of integers, see this thread:

http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=11308
The reason is the same: for the general case where an operator coverage lapse take place during multiple reporting periods.


Go to Top of Page

Ivanner
Starting Member

2 Posts

Posted - 2002-01-21 : 10:07:00
Thanks a lot Arnold. Works like a charm !

Go to Top of Page
   

- Advertisement -