Как подсчитать количество пользователей, зарегистрированных в журнале с продолжительностью на дату и 15-минутным интервалом - PullRequest
0 голосов
/ 20 октября 2019

Я хочу определить подключенных пользователей по дате и 15-минутным интервалам на основе столбцов даты и времени входа и выхода из системы и суммировать продолжительность (в секундах) этого события в зависимости от времени входа и фактического интервала. В некоторых случаях пользователи подключаются к системе более 10 часов, и подключение может завершиться на следующий день.

Поэтому у меня есть таблица интервалов с 00:00 до 23:59 с интервалом в 15 минут идругая таблица с данными для входа.

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

Вот пример данных

DECLARE @events TABLE
(
    userId VARCHAR(10)
    , loginDate DATE
    , loginTime TIME(0)
    , logoutDate DATE
    , logoutTime TIME(0)
)

INSERT INTO @events 
SELECT '1010862178', '2019-08-25', '06:56:59', '2019-08-25', '21:51:56'
UNION ALL SELECT '1010862178', '2019-08-25', '21:51:56', '2019-08-26', '13:56:24'
UNION ALL SELECT '1016063857', '2019-08-25', '05:56:10', '2019-08-25', '14:14:33'
UNION ALL SELECT '1016063857', '2019-08-25', '14:14:33', '2019-08-26', '13:58:13'

Это таблица событий

enter image description here

и результаты должны быть такими:

enter image description here

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

РЕДАКТИРОВАТЬ: таблица результатов должна начинаться так:

date        interval    usersConnected  duration
2019-08-25  05:45:00    1               230
2019-08-25  06:00:00    1               900
2019-08-25  06:15:00    1               900
2019-08-25  06:30:00    1               900
2019-08-25  06:45:00    2               1081

1 Ответ

1 голос
/ 21 октября 2019

Хорошо, после нескольких часов написания запросов, наконец-то я нашел решение, может быть, это не элегантное решение, но оно работает, поэтому теперь задача состоит в том, чтобы решить это с меньшим количеством кода.

Вотответ.

DECLARE @events TABLE
(
    userId VARCHAR(10)
    , loginDate DATE
    , loginTime TIME(0)
    , logoutDate DATE
    , logoutTime TIME(0)
)

INSERT INTO @events 
SELECT '1010862178', '2019-08-25', '06:56:59', '2019-08-25', '21:51:56'
UNION ALL SELECT '1010862178', '2019-08-25', '21:51:56', '2019-08-26', '13:56:24'
UNION ALL SELECT '1016063857', '2019-08-25', '05:56:10', '2019-08-25', '14:14:33'
UNION ALL SELECT '1016063857', '2019-08-25', '14:14:33', '2019-08-26', '13:58:13'

/* Other tables are:
    dates table:  contains only two dates '2019-08-25' and '2019-08-26'
    intervals table: contains intervals from 00:00:00 to 23:45:00
*/

select 
    convert(date, i.intervalStart) [date]
    , convert(time(0), i.intervalStart) [interval]
    , count(distinct userId) usersConnected -- distinct prevent duplicates on overlaping login and logout hours
    , sum(case 
        when datediff(second, iif([login] > i.intervalStart, [login], i.intervalStart) , iif(logout < i.intervalEnd, logout, i.intervalEnd)) < 0 then 900
        else datediff(second, iif([login] > i.intervalStart, [login], i.intervalStart) , iif(logout < i.intervalEnd, logout, i.intervalEnd))
      end) duracion
 from (
 select userId
    , [login] = CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME)
    , [logout] = CAST(logoutDate AS DATETIME) + CAST(logoutTime AS DATETIME)
 from @events ) c
 inner join (select intervalStart = CAST([date] AS DATETIME) + CAST([start] AS DATETIME)
        , intervalEnd = CAST([date] AS DATETIME) + CAST([end] AS DATETIME)
     from dbo.dates, dbo.intervals) m
     on c.[login] between  m.intervalStart and m.intervalEnd
 inner join (select
   intervalStart = CAST([date] AS DATETIME) + CAST([start] AS DATETIME)
        , intervalEnd = CAST([date] AS DATETIME) + CAST([end] AS DATETIME)
     from dbo.dates, dbo.intervals) i
 on i.intervalStart  between m.intervalStart and c.logout
 group by convert(date, i.intervalStart)
    , convert(time(0), i.intervalStart)
 order by 1, 2

Я могу изменить это с помощью перекрестного применения, но пока это работает.

Итак, он возвращает эти данные:

date    interval    usersConnected  duracion
2019-08-25  05:45:00    1   230
2019-08-25  06:00:00    1   900
2019-08-25  06:15:00    1   900
2019-08-25  06:30:00    1   900
2019-08-25  06:45:00    2   1081
2019-08-25  07:00:00    2   1800
2019-08-25  07:15:00    2   1800
2019-08-25  07:30:00    2   1800
2019-08-25  07:45:00    2   1800
2019-08-25  08:00:00    2   1800
2019-08-25  08:15:00    2   1800
2019-08-25  08:30:00    2   1800
2019-08-25  08:45:00    2   1800
2019-08-25  09:00:00    2   1800
2019-08-25  09:15:00    2   1800
2019-08-25  09:30:00    2   1800
2019-08-25  09:45:00    2   1800
2019-08-25  10:00:00    2   1800
2019-08-25  10:15:00    2   1800
2019-08-25  10:30:00    2   1800
2019-08-25  10:45:00    2   1800
2019-08-25  11:00:00    2   1800
2019-08-25  11:15:00    2   1800
2019-08-25  11:30:00    2   1800
2019-08-25  11:45:00    2   1800
2019-08-25  12:00:00    2   1800
2019-08-25  12:15:00    2   1800
2019-08-25  12:30:00    2   1800
2019-08-25  12:45:00    2   1800
2019-08-25  13:00:00    2   1800
2019-08-25  13:15:00    2   1800
2019-08-25  13:30:00    2   1800
2019-08-25  13:45:00    2   1800
2019-08-25  14:00:00    2   1800
2019-08-25  14:15:00    2   1800
2019-08-25  14:30:00    2   1800
2019-08-25  14:45:00    2   1800
2019-08-25  15:00:00    2   1800
2019-08-25  15:15:00    2   1800
2019-08-25  15:30:00    2   1800
2019-08-25  15:45:00    2   1800
2019-08-25  16:00:00    2   1800
2019-08-25  16:15:00    2   1800
2019-08-25  16:30:00    2   1800
2019-08-25  16:45:00    2   1800
2019-08-25  17:00:00    2   1800
2019-08-25  17:15:00    2   1800
2019-08-25  17:30:00    2   1800
2019-08-25  17:45:00    2   1800
2019-08-25  18:00:00    2   1800
2019-08-25  18:15:00    2   1800
2019-08-25  18:30:00    2   1800
2019-08-25  18:45:00    2   1800
2019-08-25  19:00:00    2   1800
2019-08-25  19:15:00    2   1800
2019-08-25  19:30:00    2   1800
2019-08-25  19:45:00    2   1800
2019-08-25  20:00:00    2   1800
2019-08-25  20:15:00    2   1800
2019-08-25  20:30:00    2   1800
2019-08-25  20:45:00    2   1800
2019-08-25  21:00:00    2   1800
2019-08-25  21:15:00    2   1800
2019-08-25  21:30:00    2   1800
2019-08-25  21:45:00    2   1800
2019-08-25  22:00:00    2   1800
2019-08-25  22:15:00    2   1800
2019-08-25  22:30:00    2   1800
2019-08-25  22:45:00    2   1800
2019-08-25  23:00:00    2   1800
2019-08-25  23:15:00    2   1800
2019-08-25  23:30:00    2   1800
2019-08-25  23:45:00    2   1800
2019-08-26  00:00:00    2   1800
2019-08-26  00:15:00    2   1800
2019-08-26  00:30:00    2   1800
2019-08-26  00:45:00    2   1800
2019-08-26  01:00:00    2   1800
2019-08-26  01:15:00    2   1800
2019-08-26  01:30:00    2   1800
2019-08-26  01:45:00    2   1800
2019-08-26  02:00:00    2   1800
2019-08-26  02:15:00    2   1800
2019-08-26  02:30:00    2   1800
2019-08-26  02:45:00    2   1800
2019-08-26  03:00:00    2   1800
2019-08-26  03:15:00    2   1800
2019-08-26  03:30:00    2   1800
2019-08-26  03:45:00    2   1800
2019-08-26  04:00:00    2   1800
2019-08-26  04:15:00    2   1800
2019-08-26  04:30:00    2   1800
2019-08-26  04:45:00    2   1800
2019-08-26  05:00:00    2   1800
2019-08-26  05:15:00    2   1800
2019-08-26  05:30:00    2   1800
2019-08-26  05:45:00    2   1800
2019-08-26  06:00:00    2   1800
2019-08-26  06:15:00    2   1800
2019-08-26  06:30:00    2   1800
2019-08-26  06:45:00    2   1800
2019-08-26  07:00:00    2   1800
2019-08-26  07:15:00    2   1800
2019-08-26  07:30:00    2   1800
2019-08-26  07:45:00    2   1800
2019-08-26  08:00:00    2   1800
2019-08-26  08:15:00    2   1800
2019-08-26  08:30:00    2   1800
2019-08-26  08:45:00    2   1800
2019-08-26  09:00:00    2   1800
2019-08-26  09:15:00    2   1800
2019-08-26  09:30:00    2   1800
2019-08-26  09:45:00    2   1800
2019-08-26  10:00:00    2   1800
2019-08-26  10:15:00    2   1800
2019-08-26  10:30:00    2   1800
2019-08-26  10:45:00    2   1800
2019-08-26  11:00:00    2   1800
2019-08-26  11:15:00    2   1800
2019-08-26  11:30:00    2   1800
2019-08-26  11:45:00    2   1800
2019-08-26  12:00:00    2   1800
2019-08-26  12:15:00    2   1800
2019-08-26  12:30:00    2   1800
2019-08-26  12:45:00    2   1800
2019-08-26  13:00:00    2   1800
2019-08-26  13:15:00    2   1800
2019-08-26  13:30:00    2   1800
2019-08-26  13:45:00    2   1477
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...