2015-03-04 3 views
0

Мне нужно получить максимальное количество активных пользователей по диапазону дат. Активные пользователи - это максимальное количество удаленных пользователей. У меня UsersHistory таблице:sql server: пиковые активные пользователи по дате

HistoryID UserID  IsRemoved  OperationID ModificationDate 
---------------------------------------------------------------------- 
1   1    0    'Add'  2012-07-24 04:27:48 
2   2    0    'Add'  2012-07-26 04:18:48 
3   3    0    'Add'  2012-07-27 04:29:48 
4   1    0    'Update' 2012-07-28 04:47:48 
5   2    0    'Update' 2012-07-29 04:01:48 
6   1    1    'Remove' 2012-08-28 04:34:48 
7   2    1    'Remove' 2012-08-28 04:18:48 
8   3    1    'Remove' 2012-08-28 04:29:48 
9   4    0    'Add'  2012-09-24 04:27:48 
10   5    0    'Add'  2012-09-26 04:18:48 
11   6    0    'Add'  2012-09-27 04:29:48 
12   7    0    'Add'  2012-09-27 04:29:48 

Ожидаемый результат: Максимальное количество активных пользователей этого периода: 4 (HistoryID: 9, 10, 11, 12)

Update1:

HistoryID UserID  IsRemoved  OperationID ModificationDate 
---------------------------------------------------------------------- 
1   1    0    'Add'  2012-07-24 04:27:48 
2   2    0    'Add'  2012-07-26 04:18:48 
3   3    0    'Add'  2012-07-27 04:29:48 
4   1    1    'Remove' 2012-07-28 04:47:48 
5   2    1    'Remove' 2012-07-28 04:47:48 
6   3    1    'Remove' 2012-07-28 04:47:48 

Ожидаемый результат: Максимальное количество активных (не удаленных) пользователей за указанный период: 3

+0

Я не могу понять, почему в Update1 Это 3? Если они были добавлены, а затем удалены, то их не нужно считать? Объясните мне, как это должно работать. –

ответ

0

Это должно сработать для вас. Он будет подсчитывать общее количество операций Add и общее количество операций Remove. After It subract общее кол-во Remove от общего количества Add.

DECLARE @counter1 INT, 
     @counter2 INT, 
     @result INT 

SELECT @counter1 = c1 
FROM(
    SELECT COUNT(HistoryID) AS c1 
    FROM UsersHistory 
    WHERE OperationId = 'Add' 
    ) x 
SELECT @counter2 = c2 
FROM(
    SELECT COUNT(HistoryID) AS c2 
    FROM UsersHistory 
    WHERE OperationId = 'Remove' 
    ) a 

SET @result = @counter1 - @counter2 
SELECT @result 

EDIT

Здесь вы идете (он должен рассчитывать максимум, как вам нужно):

SELECT TOP 1 COUNT(*) AS maxRes 
FROM (
    SELECT DENSE_RANK() OVER (ORDER BY UserID ASC) AS [MaximumCount], * 
    FROM UsersHistory 
    WHERE OperationId = 'Add' 
    ) a 
WHERE 
[MaximumCount] = UserID 
GROUP BY MaximumCount 
ORDER BY maxRes DESC 
+0

Это не работает ... см. Мое обновление 1 – Sergey

+0

Что именно не работает? Вы получаете сообщение об ошибке? –

+0

Неверный результат. Пожалуйста, см. Мое обновление1 в этом случае If 'Added' - 'Remoed' = 0, но в этот период максимальное число пользователей было 3. Мне нужно максимальное количество пользователей, которое было. В вашем примере показано текущее количество пользователей, но мне нужен максимум, который был. – Sergey

0

Если я вас правильно понимаю что вам нужно сделать островки на OperationID и рассчитывать максимальное количество строк в «Добавить» острова. Если да, то:

DECLARE @History TABLE 
    (
     HistoryID INT , 
     UserID INT , 
     IsRemoved BIT , 
     OperationID NVARCHAR(20) 
    ) 

INSERT INTO @History 
VALUES (1, 1, 0, 'Add'), 
     (2, 2, 0, 'Add'), 
     (3, 3, 0, 'Add'), 
     (4, 1, 1, 'Remove'), 
     (5, 2, 1, 'Remove'), 
     (6, 3, 1, 'Remove'), 
     (7, 3, 0, 'Add'); 
WITH cte1 
      AS (SELECT OperationID , 
         ROW_NUMBER() OVER (ORDER BY HistoryID) AS ID , 
         1 AS Dummy , 
         IIF(ISNULL(LAG(OperationID) OVER (ORDER BY HistoryID), 
            OperationID) = OperationID, 0, 1) AS ChangeMark 
       FROM  @History 
      ), 
     cte2 
      AS (SELECT * , 
         SUM(Dummy) OVER (ORDER BY ID) 
         + SUM(ChangeMark) OVER (ORDER BY ID) AS InervalID 
       FROM  cte1 
      ), 
     cte3 
      AS (SELECT StartSeqNo = MIN(InervalID) , 
         EndSeqNo = MAX(InervalID) 
       FROM  (SELECT InervalID , 
            rn = InervalID 
            - ROW_NUMBER() OVER (ORDER BY InervalID) 
          FROM  cte2 
         ) a 
       GROUP BY rn 
      ), 
     cte4 
      AS (SELECT COUNT(*) AS C 
       FROM  cte2 c2 
         JOIN cte3 c3 ON c2.InervalID BETWEEN c3.StartSeqNo AND  c3.EndSeqNo 
       WHERE c2.OperationID = 'Add' 
       GROUP BY c3.EndSeqNo 
      ) 
    SELECT MAX(c) AS UserCount 
    FROM cte4 
Смежные вопросы