2014-12-30 3 views
1

Я работаю в среде call-центра здравоохранения. У меня есть доступ к базе данных нашей основной системы, и я хочу использовать данные в ней, чтобы определить количество сотрудников, зарегистрированных в каждый час данных за определенный период, которые могут увеличиваться в течение 24 часов (например, 24/12/2014 - 26/12/2014).SQL max одновременных сеансов в час дня

Существует userlog таблица, которая записывает, когда пользователи входят в систему и выходят из системы.

userlog таблица Пример

UserRef         Date     LogType SessionID 
--------------------------------------- ----------------------- ------ ----------------------- 
96AD647C-D061-43F5-9F8D-FA6C74817E07 2002-10-17 14:11:25.763 LOGON 8D451569-0260-46BB-9B9E-F49B3E778161  
96AD647C-D061-43F5-9F8D-FA6C74817E07 2002-10-17 18:11:32.547 LOGOFF 8D451569-0260-46BB-9B9E-F49B3E778161  
60738820-5F72-4E20-A070-57E07C83B6DE 2002-10-17 14:53:31.153 LOGON C773894C-8B2D-4054-A550-3F04B4C5669F  
60738820-5F72-4E20-A070-57E07C83B6DE 2002-10-17 22:55:25.607 LOGOFF C773894C-8B2D-4054-A550-3F04B4C5669F 
90A55FDD-967E-4D99-96DF-96840CDB2CDF 2002-10-17 15:26:40.123 LOGON 1CE5F5A5-4E20-4D4A-BB67-EB0CB33976D7  
96AD647C-D061-43F5-9F8D-FA6C74817E07 2002-10-17 15:51:28.590 LOGON 7EFDEE1C-15CF-4DE1-B59F-7AFC49B4BE73  
90A55FDD-967E-4D99-96DF-96840CDB2CDF 2002-10-17 15:58:05.217 LOGOFF 1CE5F5A5-4E20-4D4A-BB67-EB0CB33976D7  
96AD647C-D061-43F5-9F8D-FA6C74817E07 2002-10-17 15:58:31.013 LOGOFF 7EFDEE1C-15CF-4DE1-B59F-7AFC49B4BE73  
90A55FDD-967E-4D99-96DF-96840CDB2CDF 2002-10-17 15:58:32.733 LOGON 03F56AB8-FED5-4CC7-8445-26BF55F58E60  
90A55FDD-967E-4D99-96DF-96840CDB2CDF 2002-10-17 16:13:02.827 LOGOFF 03F56AB8-FED5-4CC7-8445-26BF55F58E60  

Желаемые результаты(это не предназначено, чтобы отразить вышеуказанные данные примера):

Date   Hour Number of users logged in 
----   ---- ------------------------- 
01/12/2014 0     0 
01/12/2014 1     0 
01/12/2014 2     0 
01/12/2014 3     0 
01/12/2014 4     0 
01/12/2014 5     1 
01/12/2014 6     1 
01/12/2014 7     1 
01/12/2014 8     3 
01/12/2014 9     7 
01/12/2014 10     7 
...     
01/12/2014 23     0 

быть ясным: I» m, пытаясь получить час, чтобы по-прежнему отображаться с подсчетом 0, когда пользователей не было зарегистрировано.

Я предполагаю, что то, что я ищу, - это максимальные параллельные сеансы для каждого часа дня, но я не слишком технический или квалифицированный в SQL (понемногу получается, хотя!), Поэтому я надеюсь, что эта терминология не путает вещи!

Я искал это для поиска и нашел несколько подобных сценариев, но для Oracle и MySQL, или где таблица журналов записывает данные входа по-разному. Я уверен, что я доберусь до точки, где я могу успешно перевести другой код запроса базы данных на MS SQL, но я еще нет!

Я использую: Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86).

Заранее за вашу помощь.

+0

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

+0

@DeepakPawar Да, я это сделаю. Я не получил нигде с попытками, кроме как получить его в таблицу с заголовками столбцов идентификатора сеанса, датой входа в систему, датой выхода из системы. Я не знал, куда идти оттуда. К сожалению :( – jjswin

ответ

1

ОБНОВЛЕНО (v # 4):

Я добавил фильтр даты в конце запроса - WHERE A.[Date] Between @X and @Y - это не самый эффективный способ в этом случае, но простейшие я думаю, и меньше ошибок для начало:

SELECT 
    A.[Date], 
    A.[Hour], 
    SUM(CASE WHEN (B.[SessionID] IS NULL) THEN 0 ELSE 1 END) AS [Number_of_Sessions_Per_Hour] 
FROM 
(
    SELECT DISTINCT 
     CONVERT(DATETIME, 
      LTRIM(RTRIM(CONVERT(NVARCHAR(10), YEAR(userlog.[Date])))) 
      + '-' + RIGHT('0' + LTRIM(RTRIM(CONVERT(NVARCHAR(10), MONTH(userlog.[Date])))), 2) 
      + '-' + RIGHT('0' + LTRIM(RTRIM(CONVERT(NVARCHAR(10), DAY(userlog.[Date])))), 2) 
      , 120) AS [Date], 
     hours_table.[Hour] 
    FROM 
     userlog, 
     (
      SELECT 1 AS [Hour] UNION ALL SELECT 3 AS [Hour] UNION ALL SELECT 4 AS [Hour] UNION ALL SELECT 5 AS [Hour] UNION ALL SELECT 6 AS [Hour] 
      UNION ALL SELECT 7 AS [Hour] UNION ALL SELECT 7 AS [Hour] UNION ALL SELECT 8 AS [Hour] UNION ALL SELECT 9 AS [Hour] UNION ALL SELECT 10 AS [Hour] 
      UNION ALL SELECT 11 AS [Hour] UNION ALL SELECT 12 AS [Hour] UNION ALL SELECT 13 AS [Hour] UNION ALL SELECT 14 AS [Hour] UNION ALL SELECT 15 AS [Hour] 
      UNION ALL SELECT 16 AS [Hour] UNION ALL SELECT 17 AS [Hour] UNION ALL SELECT 18 AS [Hour] UNION ALL SELECT 19 AS [Hour] UNION ALL SELECT 20 AS [Hour] 
      UNION ALL SELECT 21 AS [Hour] UNION ALL SELECT 22 AS [Hour] UNION ALL SELECT 23 AS [Hour] UNION ALL SELECT 24 AS [Hour] 
     ) as hours_table 
) AS A 
LEFT OUTER JOIN 
(
    SELECT 
     userlog.SessionID, 
     MAX(CASE WHEN userlog.LogType = 'LOGON' 
       THEN CONVERT(DATETIME, 
         LTRIM(RTRIM(CONVERT(NVARCHAR(10), YEAR(userlog.[Date])))) 
         + '-' + RIGHT('0' + LTRIM(RTRIM(CONVERT(NVARCHAR(10), MONTH(userlog.[Date])))), 2) 
         + '-' + RIGHT('0' + LTRIM(RTRIM(CONVERT(NVARCHAR(10), DAY(userlog.[Date])))), 2) 
         , 120) 
       ELSE CONVERT(DATETIME, '1900-01-01', 120) 
      END) AS [Date_Session_START], 
     MAX(CASE WHEN userlog.LogType = 'LOGOFF' 
       THEN CONVERT(DATETIME, 
         LTRIM(RTRIM(CONVERT(NVARCHAR(10), YEAR(userlog.[Date])))) 
         + '-' + RIGHT('0' + LTRIM(RTRIM(CONVERT(NVARCHAR(10), MONTH(userlog.[Date])))), 2) 
         + '-' + RIGHT('0' + LTRIM(RTRIM(CONVERT(NVARCHAR(10), DAY(userlog.[Date])))), 2) 
         , 120) 
       ELSE CONVERT(DATETIME, '1900-01-01', 120) 
      END) AS [Date_Session_END], 
     MAX(CASE WHEN userlog.LogType = 'LOGON' THEN DATEPART(HOUR, userlog.[Date]) ELSE 0 END) AS [Hour_Session_START], 
     MAX(CASE WHEN userlog.LogType = 'LOGOFF' THEN DATEPART(HOUR, userlog.[Date]) ELSE 0 END) AS [Hour_Session_END], 
    FROM 
     userlog 
    GROUP BY 
     userlog.SessionID 
) AS B 
    ON (A.[Date] >= B.[Date_Session_START] AND A.[Date] <= B.[Date_Session_END]) 
     AND (A.[Hour] >= B.[Hour_Session_START] AND A.[Hour] <= B.[Hour_Session_END]) 
WHERE 
    A.[Date] Between @X and @Y 
GROUP BY 
    A.[Date], 
    A.[Hour] 
+0

Привет, результаты выглядят немного низко - это ваш запрос, подсчитывающий количество событий входа в час или количество активных сеансов в час (т.вы все равно получите счет, если пользователь еще не вышел из системы, но зарегистрировался в предыдущий час). EDIT - извините, я тоже хотел поблагодарить вас за ответ :) – jjswin

+0

Нет проблем :) Пожалуйста, сообщите, какие строки следует забрать, чтобы получить результат? Все или 'LogType = 'LOGON'' или' LogType =' LOGOFF'' - и должны ли они подсчитывать сеансы или пользователей в час? Или, может быть, сеансы на пользователя в час? –

+0

В каждом часе дня должно учитываться любые сеансы, в которых час дня равен или больше часа времени и времени LOGON, но меньше или равно часу дня и времени LOGOFF. – jjswin

0

ОК, принят несколько иной подход. Я создаю таблицу Logon/Log Off - которая может быть в cte, но Im не эксперт оракула, поэтому не уверен, что ее поддерживали так, чтобы упростить SQL и временную таблицу. Я все построил таблицу статических целых чисел (также называемую таблицей таблиц) для 0-30, чтобы обрабатывать диапазон дат теста в моем запросе на основе вашего ответа выше - если у вас есть уже один, вы можете просто использовать этот диапазон и сохранить некоторые усилия. Выполнение запроса возвращает таблицу, как это (используя данные примеры также ниже)

StartDate WorkingHour LoggedInUsers 
2002-10-17 00:00:00.000 10 0 
2002-10-17 00:00:00.000 11 0 
2002-10-17 00:00:00.000 12 0 
2002-10-17 00:00:00.000 13 0 
2002-10-17 00:00:00.000 14 2 
2002-10-17 00:00:00.000 15 5 
2002-10-17 00:00:00.000 16 3 
2002-10-17 00:00:00.000 17 2 
2002-10-17 00:00:00.000 18 2 
2002-10-17 00:00:00.000 19 1 
2002-10-17 00:00:00.000 20 1 
2002-10-17 00:00:00.000 21 1 
2002-10-17 00:00:00.000 22 1 
2002-10-17 00:00:00.000 23 0 

код Запускать в SQL

DECLARE @StartDate DATETIME , 
@NoDays INT ; 


select 
@StartDate = '2002-10-01', 
@NoDays = 20; 



DECLARE @Sessions TABLE (
UserRef UNIQUEIDENTIFIER, 
DATE DATETIME, 
LogType VARCHAR(100), 
SessionID UNIQUEIDENTIFIER 
); 
INSERT INTO @Sessions 
SELECT '96AD647C-D061-43F5-9F8D-FA6C74817E07', '2002-10-17 14:11:25.763', 'LOGON', '8D451569-0260-46BB-9B9E-F49B3E778161' 
UNION SELECT '96AD647C-D061-43F5-9F8D-FA6C74817E07', '2002-10-17 18:11:32.547', 'LOGOFF', '8D451569-0260-46BB-9B9E-F49B3E778161' 
UNION SELECT '60738820-5F72-4E20-A070-57E07C83B6DE', '2002-10-17 14:53:31.153', 'LOGON', 'C773894C-8B2D-4054-A550-3F04B4C5669F' 
UNION SELECT '60738820-5F72-4E20-A070-57E07C83B6DE', '2002-10-17 22:55:25.607', 'LOGOFF', 'C773894C-8B2D-4054-A550-3F04B4C5669F' 
UNION SELECT '90A55FDD-967E-4D99-96DF-96840CDB2CDF', '2002-10-17 15:26:40.123', 'LOGON', '1CE5F5A5-4E20-4D4A-BB67-EB0CB33976D7' 
UNION SELECT '96AD647C-D061-43F5-9F8D-FA6C74817E07', '2002-10-17 15:51:28.590', 'LOGON', '7EFDEE1C-15CF-4DE1-B59F-7AFC49B4BE73' 
UNION SELECT '90A55FDD-967E-4D99-96DF-96840CDB2CDF', '2002-10-17 15:58:05.217', 'LOGOFF', '1CE5F5A5-4E20-4D4A-BB67-EB0CB33976D7' 
UNION SELECT '96AD647C-D061-43F5-9F8D-FA6C74817E07', '2002-10-17 15:58:31.013', 'LOGOFF', '7EFDEE1C-15CF-4DE1-B59F-7AFC49B4BE73' 
UNION SELECT '90A55FDD-967E-4D99-96DF-96840CDB2CDF', '2002-10-17 15:58:32.733', 'LOGON', '03F56AB8-FED5-4CC7-8445-26BF55F58E60' 
UNION SELECT '90A55FDD-967E-4D99-96DF-96840CDB2CDF', '2002-10-17 16:13:02.827', 'LOGOFF', '03F56AB8-FED5-4CC7-8445-26BF55F58E60'; 


DECLARE @staticintegers TABLE (myInteger INT); 
INSERT INTO @staticintegers 
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13 
UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 UNION SELECT 17 UNION SELECT 18 
UNION SELECT 19 UNION SELECT 20 UNION SELECT 21 UNION SELECT 22 UNION SELECT 23 
UNION SELECT 24 UNION SELECT 25 UNION SELECT 26 UNION SELECT 27 UNION SELECT 28 
UNION SELECT 29 UNION SELECT 30 UNION SELECT 31 UNION SELECT 32 UNION SELECT 33; 

DECLARE @sessionsOutput TABLE (SessionID UNIQUEIDENTIFIER, StartTime DATETIME, EndTime DATETIME); 
INSERT INTO @sessionsOutput 
(SessionID, StartTime) 
SELECT 
    SessionID, 
    [date] 
FROM 
    @Sessions 
    WHERE logtype = 'Logon'; 

UPDATE @sessionsOutput 
SET EndTime = [date] 
FROM @sessionsOutput aa 
INNER JOIN @Sessions bb 
ON aa.SessionID = bb.SessionID 
WHERE bb.LogType = 'Logoff'; 



SELECT 
    DATEADD(dd, DateIntegers.myInteger, @StartDate) AS StartDate 
    ,hoursintegers.myINteger AS WorkingHour 
    ,COUNT(aa.SessionID) AS LoggedInUsers 


FROM 
    @staticintegers DateIntegers 
    LEFT OUTER JOIN @StaticIntegers HoursIntegers 
    ON HoursIntegers.myInteger BETWEEN 0 AND 23 

LEFT OUTER JOIN @sessionsOutput aa 
ON 
    HoursIntegers.myInteger BETWEEN DATEPART(hh, aa.StartTime) AND DATEPART(hh, aa.endtime) 
    AND CAST(aa.StartTime AS DATE) = DATEADD(dd, dateintegers.myInteger, @StartDate) 

GROUP BY 
    DATEADD(dd, DateIntegers.myInteger, @StartDate), 
    HoursIntegers.myInteger 
ORDER BY 
    DATEADD(dd, DateIntegers.myInteger, @StartDate), 
    HoursIntegers.myInteger; 
+0

Привет! Спасибо. Тем не менее, я еще не работал. Мне пришлось возиться с SQL, поскольку он стонал, что переменные не были объявлены (я добавил бит SET), а затем о дате, не являющейся допустимым типом. Во всяком случае, я запустил его, и он возвращает 0 за каждый час. – jjswin

+0

Прошло некоторое время с тех пор, как я был в SQL 2005; подключен к одному и пробовал его; изменив заголовок на - объявить, а затем выберите (может; t сделать в комментарии, но будет обновлять запрос выше) Выполнение этого Позволяет мне выполнить запрос, представленный в 2005 году, без прокрутки до 17-го числа (на ваш пример данных - запрос возвращается из нескольких дней с даты начала, которую я использую как 1 октября 2002 года в примере, как это было непосредственно перед вашими примерными данными). Я все еще вижу результаты, опубликованные. – u07ch

Смежные вопросы