Подсчет количества «перекрывающихся» строк в SQL Server - PullRequest
6 голосов
/ 01 марта 2010

Меня попросили взглянуть на базу данных, в которой записываются данные о входе и выходе пользователя из системы - есть столбец для времени входа в систему и еще один столбец для записи выхода из системы, оба в формате OLE. Мне нужно собрать некоторую информацию о параллелизме пользователей - то есть, сколько пользователей вошли в систему в одно и то же время каждый день.

Кто-нибудь знает, как это сделать в SQL? Мне не нужно знать детали, только счет в день.

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

Ответы [ 3 ]

2 голосов
/ 01 марта 2010

Самый простой способ - создать таблицу times_table из таблицы вспомогательных чисел (добавив от 0 до 24 * 60 минут к базовому времени), чтобы получать каждый раз в течение определенного 24-часового периода:

SELECT MAX(simul) FROM (
    SELECT test_time
        ,COUNT(*) AS simul
    FROM your_login_table
    INNER JOIN times_table -- a table/view/subquery of all times during the day
        ON your_login_table.login_time <= times_table.test_time AND times_table.test_time <= your_login_table.logout_time
    GROUP BY test_time
) AS simul_users (test_time, simul)
1 голос
/ 01 марта 2010

Не проверено ... но теряются значения даты, отсчитывается время между ними, используйте "конец дня" для еще вошедшего в систему.

Предполагается, что "logintime" - это дата и время. Если нет, производная таблица может быть удалена (все еще требуется ISNULL, хотя). Конечно, у SQL Server 2008 есть «время», чтобы сделать это проще.

SELECT
    COUNT(*)
FROM
    (
    SELECT
         DATEADD(day, DATEDIFF(day, logintime, 0), logintime) AS inTimeOnly,
         ISNULL(DATEADD(day, DATEDIFF(day, logouttime, 0), logintime), '1900-01-01 23:59:59.997') AS outTimeOnly
    FROM
         mytable
    ) foo
WHERE
    inTimeOnly >= @TheTimeOnly AND outTimeOnly <= @TheTimeOnly
1 голос
/ 01 марта 2010

Я думаю, что это будет работать.

Select C.Day, Max(C.Concurrency) as MostConcurrentUsersByDay
FROM 
(
   SELECT convert(varchar(10),L1.StartTime,101) as day, count(*) as Concurrency
   FROM login_table L1
   INNER JOIN login_table L2 
      ON (L2.StartTime>=L1.StartTime AND L2.StartTime<=L1.EndTime) OR
         (L2.EndTime>=L1.StartTime AND L2.EndTime<=L1.EndTime)
    WHERE (L1.EndTime is not null) and L2.EndTime Is not null)  AND (L1.ID<>L2.ID)
    GROUP BY convert(varchar(10),L1.StartTime,101)
) as C    
Group BY C.Day
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...