Группировать по данным, чтобы получить счетчик между диапазоном дат и времени - PullRequest
0 голосов
/ 30 января 2019

Допустим, у меня есть таблица, как показано ниже

start_time           end_time             user_name
2019-01-01 00:00:05  2019-01-01 00:05:05  user1
2019-01-01 00:01:35  2019-01-01 00:06:05  user2
2019-01-01 00:02:05  2019-01-01 00:07:05  user3
2019-01-01 00:03:05  2019-01-01 00:08:05  user1
2019-01-01 00:04:05  2019-01-01 00:09:05  user2

Моя цель - узнать, сколько пользователей вошли в систему для МИНУТЫ .Скажите, как показано ниже

time                  active no of users
2019-01-01 00:00:00   1
2019-01-01 00:01:00   2
2019-01-01 00:02:00   3
2019-01-01 00:03:00   3
2019-01-01 00:04:00   3

Теперь я впервые попытался округлить время для нового столбца dateadd(mi, datediff(mi, 0, dateadd(s, 30, start_time)), 0).Итак, я получу, как указано выше в таблице time столбец

Далее я попытался найти счетчик для округленной даты и времени, как показано ниже:

SELECT
dateadd(mi, datediff(mi, 0, dateadd(s, 30, start_time)), 0) as RoundedDateTime,
(
    SELECT  count(distinct(user_name)) 
    FROM entrytable sh
    WHERE (sh.end_time > dateadd(mi, datediff(mi, 0, dateadd(s, 30, t.start_time)), 0) 
    and sh.start_time <= dateadd(mi, datediff(mi, 0, dateadd(s, 30, t.start_time)), 0))        
) as usercounter
FROM entrytable t 

Но вышеупомянутый SQL-запрос выполняется дольше ипереходит в не отвечающий режим.

Я не смог решить проблему.Может кто-нибудь помочь?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Этот вопрос был изначально помечен для SQL Server 2012 , поэтому этот ответ предназначен для SQL Server.

Один из способов - создать список минут, а затем:

with minutes as (
      select cast('2019-01-01 00:00:00' as datetime) as mm
      union all
      select dateadd(minute, 1, minute)
      from cte
      where mm < '2019-01-01 00:00:05'
     )
select m.*,
       (select count(*)
        from entrytable et
        where et.start_time <= m.mm and
              et.end_time > m.mm
       ) as num_actives
from minutes m;
0 голосов
/ 30 января 2019

Наиболее тривиальным решением является следующее:

DECLARE @t TABLE (start_time datetime, end_time datetime, user_name varchar(10));
INSERT INTO @t VALUES
('2019-01-01 00:00:05', '2019-01-01 00:05:05', 'user1'),
('2019-01-01 00:01:35', '2019-01-01 00:06:05', 'user2'),
('2019-01-01 00:02:05', '2019-01-01 00:07:05', 'user3'),
('2019-01-01 00:03:05', '2019-01-01 00:08:05', 'user1'),
('2019-01-01 00:04:05', '2019-01-01 00:09:05', 'user2');

SELECT dt AS date_time, SUM(SUM(val)) OVER (ORDER BY dt) AS active_count
FROM (
    SELECT start_time, +1 FROM @t UNION ALL
    SELECT end_time,   -1 FROM @t
) cte1(dt, val)
GROUP BY dt

Это даст вам количество активных пользователей, когда произошли изменения (кто-то входил или выходил из системы).Результат:

| date_time               | active_count |
|-------------------------|--------------|
| 2019-01-01 00:00:05.000 | 1            |
| 2019-01-01 00:01:35.000 | 2            |
| 2019-01-01 00:02:05.000 | 3            |
| 2019-01-01 00:03:05.000 | 4            |
| 2019-01-01 00:04:05.000 | 5            |
| 2019-01-01 00:05:05.000 | 4            |
| 2019-01-01 00:06:05.000 | 3            |
| 2019-01-01 00:07:05.000 | 2            |
| 2019-01-01 00:08:05.000 | 1            |
| 2019-01-01 00:09:05.000 | 0            |

Имейте в виду, что результат не содержит промежуточных дат.

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