Рассчитать минимальное и максимальное время входа в систему и выхода из системы в SQL Server с событиями входа - PullRequest
0 голосов
/ 18 июня 2019

У меня есть таблица входа в систему и выхода из системы операторов центра обработки вызовов, эти агенты имеют рабочую смену с 22 на 06, поэтому мне нужно рассчитать минимум loginTime и максимум logOutTime, но здесь все становится сложным, потому чтоесть случаи, когда агент отключается в течение этого временного диапазона, затем в тот же день, когда начинается другая смена, в базе данных создается другое событие входа в систему и т. д.

Я пытался управлять результатами с помощью функций ROW_NUMBERи используя MIN и MAX с ROWS PRECEDING и FOLLOWING, но это не сработало, мой код:

SELECT  agentId
       ,position
       ,loginDate
       ,loginTime
       ,logoutDate
       ,logoutTime
       ,MIN((CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME)))
             OVER(PARTITION BY agentId, position ORDER BY agentId, loginDate, loginTime) minLoginTime
       ,MAX((CAST(logoutDate AS DATETIME) + CAST(logoutTime AS DATETIME)))
       OVER(PARTITION BY agentId, position ORDER BY agentId, loginDate, loginTime ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING) maxLogoutTime
FROM @tbl
ORDER BY loginDate
       ,loginTime
       ,logoutDate
       ,logoutTime

Это пример таблицы:

DECLARE @tbl TABLE(agentId VARCHAR(10), position VARCHAR(10), loginDate DATE, loginTime TIME(0), logoutDate DATE, logoutTime TIME(0))

INSERT INTO @tbl SELECT '311338', '230025', '2019-06-03', '21:59:00', '2019-06-04', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230025', '2019-06-04', '21:59:00', '2019-06-04', '23:30:00'
INSERT INTO @tbl SELECT '311338', '230025', '2019-06-04', '23:31:00', '2019-06-05', '06:01:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-05', '21:59:00', '2019-06-06', '02:13:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-06', '02:14:00', '2019-06-06', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230037', '2019-06-06', '22:00:00', '2019-06-07', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-07', '21:59:00', '2019-06-08', '00:53:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-08', '00:53:00', '2019-06-08', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-09', '22:00:00', '2019-06-10', '06:09:00'

SELECT agentId
    ,position
    ,(CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME)) loginTime
    ,(CAST(logoutDate AS DATETIME) + CAST(logoutTime AS DATETIME)) logoutTime
  FROM @tbl

Ожидаемый результат для agentId 311338будет:

День 2019-05-06: minLogin = 2019-06-05 21: 59: 00.000 maxLogout = 2019-06-06 06: 00: 00.000

День 2019-06-06: minLogin = 2019-06-06 22: 00: 00.000 maxLogout = 2019-06-07 06: 00: 00.000

День 2019-06-07: minLogin = 2019-06-07 21:59: 00.000 maxLogout = 2019-06-08 06: 00: 00.000

Day ....

Asвы можете видеть, что не нужно сбрасывать время, если в одну и ту же дату происходит более одного события входа в систему, я должен проверить, является ли оно частью последней дневной смены или частью следующей дневной смены.

Надеюсь, выребята, можете помочь мне.

Ответы [ 2 ]

2 голосов
/ 18 июня 2019

Пока люди не прекращают свою смену после 08:00, это будет работать для вас (я немного изменил ваш стол для простоты)

DECLARE @tbl TABLE(agentId VARCHAR(10), loginMoment DATETIME, logoutMoment DATETIME)

INSERT INTO @tbl SELECT '311338', '2019-06-03 21:59:00', '2019-06-04 06:00:00'
INSERT INTO @tbl SELECT '311338', '2019-06-04 21:59:00', '2019-06-04 23:30:00'
INSERT INTO @tbl SELECT '311338', '2019-06-04 23:31:00', '2019-06-05 06:01:00'
INSERT INTO @tbl SELECT '311338', '2019-06-05 21:59:00', '2019-06-06 02:13:00'
INSERT INTO @tbl SELECT '311338', '2019-06-06 02:14:00', '2019-06-06 06:00:00'
INSERT INTO @tbl SELECT '311338', '2019-06-06 22:00:00', '2019-06-07 06:00:00'
INSERT INTO @tbl SELECT '311338', '2019-06-07 21:59:00', '2019-06-08 00:53:00'
INSERT INTO @tbl SELECT '311338', '2019-06-08 00:53:00', '2019-06-08 06:00:00'
INSERT INTO @tbl SELECT '311338', '2019-06-09 22:00:00', '2019-06-10 06:09:00'


SELECT agentId
    ,DATEADD(HOUR, 8, MIN(DATEADD(HOUR, -8, loginMoment)))
    ,DATEADD(HOUR, 8, MAX(DATEADD(HOUR, -8, logoutMoment)))
FROM @tbl
GROUP BY agentId, CAST(DATEADD(HOUR, -8, loginMoment) AS DATE)

Результат соответствует заданному вами:

agentId login logout
311338  03/06/2019 21:59:00 04/06/2019 06:00:00
311338  04/06/2019 21:59:00 05/06/2019 06:01:00
311338  05/06/2019 21:59:00 06/06/2019 06:00:00
311338  06/06/2019 22:00:00 07/06/2019 06:00:00
311338  07/06/2019 21:59:00 08/06/2019 06:00:00
311338  09/06/2019 22:00:00 10/06/2019 06:09:00
0 голосов
/ 18 июня 2019

Насколько я вижу, интересующий вас «день» на 6 часов отстает от обычного дня - так что попробуйте GROUP BY DATE на 6 часов позже DATE / TIME

для более подробного объяснения, я беру время входа в систему и вычитаю 6 часов, затем беру часть даты для группировки по (условной дате)

    SELECT  agentId, 
        CAST(DATEADD(hour,-6,CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME)) AS DATE) NotionalDate
        ,min((CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME))) minloginTime
        ,max((CAST(logoutDate AS DATETIME) + CAST(logoutTime AS DATETIME))) maxlogoutTime
    FROM @tbl 
        group by agentId, 
            CAST(DATEADD(hour,-6,CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME)) AS DATE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...