SQL keeping count of occurrences through a sliding window

[亡魂溺海] 提交于 2020-01-04 06:44:14

问题


In the previous question (Please refer to: SQL Keeping count of occurrences) I needed to count the number of occurrences of a variable.

The code provided was as follows:

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

However, now I need to introduce an improvement to that code:

Let's say that I have the following table:

   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

Now, I need to count the number of occurrences in a specific period of time. The desired output would be as follows (supposing a time frame of n=2 days, for the sake of simplicity)

    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

That is, I need to know how many times the code 'x' has appeared in my table in the last 'n' months.

This is run in SQL Server 2012.

Thank you in advance.


回答1:


Use option with CTE, CROSS APPLY operator and ROW_NUMBER ranking function

 ;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]

Demo on SQLFiddle

For improving performance use this index

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



回答2:


Please try:

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



回答3:


Try this query

Query 1:

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

Results:

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

If you want count for all the code values then remove the where clause..

SQLFIDDLE

Hope this helps




回答4:


Try this

     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];

Or Try this.

 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];


来源:https://stackoverflow.com/questions/15876511/sql-keeping-count-of-occurrences-through-a-sliding-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!