SQL通过滑动窗口保持发生次数

时间:2013-04-08 10:11:56

标签: sql sql-server count sql-server-2012

在上一个问题中(请参阅:SQL Keeping count of occurrences)我需要计算一个变量的出现次数。

提供的代码如下:

SELECT 
    [Date], Code, 
    [Count] = COUNT(*) OVER (PARTITION BY Code ORDER BY [Date] ROWS UNBOUNDED PRECEDING)
FROM dbo.YourTable
ORDER BY [Date];

但是,现在我需要对该代码进行改进:

假设我有下表:

   Date          | Code
   ------------------------
   2010/01/01    | 25
   2010/01/01    | 22
   2010/01/01    | 23
   2010/01/01    | 25
   2010/01/02    | 23
   2010/01/02    | 23
   2010/01/03    | 23
   2010/01/04    | 23
   2010/01/05    | 23
   2010/01/06    | 23
   2010/01/07    | 23
   .....
   2013/03/02    | 21

现在,我需要计算特定时间段内的出现次数。期望的输出如下(假设n = 2天的时间范围,为了简单起见)

    Date         | Code  |  Occurrences
   ------------------------------------
   2010/01/01    | 25    |      1
   2010/01/01    | 22    |      1
   2010/01/01    | 23    |      1
   2010/01/01    | 25    |      2
   2010/01/02    | 23    |      2
   2010/01/02    | 23    |      3
   2010/01/03    | 23    |      3 -> We are not considering the occurence in 2011/01/01 as it is out of the scope now
   2010/01/04    | 23    |      2 -> Considers only occurrences in 01/03 and 01/04 
   2010/01/05    | 23    |      2
   2010/01/06    | 23    |      2
   2010/01/07    | 23    |      2
   .....
   2013/03/02    |  21   |      1

也就是说,我需要知道代码“x”在过去'n'个月内出现在我的表中的次数。

这在SQL Server 2012中运行。

提前谢谢。

4 个答案:

答案 0 :(得分:1)

使用CTECROSS APPLY运算符和ROW_NUMBER排名函数

的选项
 ;WITH cte AS
 (
  SELECT [Date], Code
  FROM dbo.YourTable  
  GROUP BY [Date], Code
  )
  SELECT c.Date, c.Code, o.Occurrences
  FROM cte c 
    CROSS APPLY (
                 SELECT t2.[Date], t2.Code,
                        ROW_NUMBER() OVER(PARTITION BY c.[Date] ORDER BY t2.[Date]) AS Occurrences        
                 FROM dbo.YourTable t2
                 WHERE c.Code = t2.Code
                   AND DATEDIFF(day, t2.[Date], c.[Date]) BETWEEN 0 AND 1
                 ) o
  WHERE c.Code = o.Code AND c.[Date] = o.[Date] 
  ORDER BY c.[Date]

SQLFiddle上的演示

为了提高性能,请使用此索引

CREATE INDEX x ON dbo.YourTable([Date], Code)

答案 1 :(得分:0)

试试这个

     SELECT * FROM 
            (SELECT 
            ROW_NUMBER() OVER (PARTITION BY Code,[Date] ORDER BY [Date]) AS NO,
            [Date], Code, 
            COUNT(1) OVER (PARTITION BY Code ,[Date]) AS [Count] 
        FROM dbo.YourTable Where date between dateadd(m, -n, GETDATE()) and GETDATE() ) 
AS T1 WHERE No = 1
        ORDER BY [Date];

或试试这个。

 SELECT * FROM 
                (SELECT 
                ROW_NUMBER() OVER (PARTITION BY Code,[Date] ORDER BY [Date]) AS NO,
                [Date], Code, 
                COUNT(1) OVER (PARTITION BY Code ,[Date]) AS [Count] 
            FROM dbo.YourTable Where 
    Code = 25 And
    date between dateadd(m, -n, GETDATE()) and GETDATE() ) AS T1 WHERE No = 1
            ORDER BY [Date];

答案 2 :(得分:0)

请尝试:

SELECT 
    *, 
    ROW_NUMBER() OVER (PARTITION BY Code ORDER BY Code) Occurrences 
FROM YourTable
ORDER BY Occurrences

答案 3 :(得分:0)

尝试此查询

查询1

select 
  count(*) as CountOccurance,
  code
from 
  tbl 
where 
  code = 21 and 
  date between dateadd(m, -5, SYSDATETIME ()) and SYSDATETIME ()
group by 
  code

<强>结果:

| COUNTOCCURANCE | CODE |
-------------------------
|              1 |   21 |

如果要计算所有代码值,请删除where子句..

SQLFIDDLE

希望这有帮助