sql server:按日期范围的活跃用户数

时间:2015-03-04 11:14:13

标签: sql sql-server

我需要按日期范围计算最大活跃用户数。 Acrive用户 - 最大数量的未删除用户。 我有UsersHistory表:

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(历史ID: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

2 个答案:

答案 0 :(得分:0)

这对你有用。它将计算Add的总操作数和Remove的总操作数。在它从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

修改

这里你去(它应该根据你的需要计算最大值):

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

答案 1 :(得分: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