sqlserver中的窗口移动平均

sqlserver中的窗口移动平均,sql,sql-server-2008,moving-average,Sql,Sql Server 2008,Moving Average,我正在尝试创建一个函数,用于计算SQLServer2008中的窗口移动平均值。我对SQL非常陌生,所以我遇到了一些困难。我尝试对其执行移动平均的数据需要按天分组(都是时间戳数据),然后需要对其应用可变移动平均窗口 我已经有了一个按天(和@id)对数据进行分组的函数,该函数显示在底部。我有几个问题: 在移动平均值函数中调用分组函数更好,还是一次调用所有函数更好? 是否可以获取输入函数的日期的移动平均值,但返回n天开始移动平均值,以便返回数据的前n天的平均值不为0?(即,如果他们想要从2011年8月

我正在尝试创建一个函数,用于计算SQLServer2008中的窗口移动平均值。我对SQL非常陌生,所以我遇到了一些困难。我尝试对其执行移动平均的数据需要按天分组(都是时间戳数据),然后需要对其应用可变移动平均窗口

我已经有了一个按天(和@id)对数据进行分组的函数,该函数显示在底部。我有几个问题:

在移动平均值函数中调用分组函数更好,还是一次调用所有函数更好?

是否可以获取输入函数的日期的移动平均值,但返回n天开始移动平均值,以便返回数据的前n天的平均值不为0?(即,如果他们想要从2011年8月1日到2011年8月2日的7天移动平均线,我将在2011年1月1日开始移动平均线计算,以便他们定义的第一天有一个值?)

我正在研究如何进行移动平均,并且知道移动窗口似乎是最好的选择(currentSum=prevSum+todayCount-nthDayAgoCount)/nDays,但我仍在研究这一点的SQL实现

我有一个类似这样的分组函数(出于可见性目的删除了一些变量):

编辑:回答我提出的第一个问题:


我最终创建了一个函数,该函数声明了一个临时表,并将count函数的结果插入其中,然后使用
user662852
中的示例计算移动平均值。

将硬编码的日期范围从查询中取出。将输出(如末尾的示例)写入临时表(我称之为下面的访问)。
尝试将此自连接到临时表:

 Select list.dtadmission
   , AVG(data.nvisits) as Avg
   , SUM(data.nvisits) as sum
   , COUNT(data.nvisits) as RollingDayCount
   , MIN(data.dtadmission) as Verifymindate
   , MAX(data.dtadmission)   as Verifymaxdate
 from  #visits as list 
 inner join #visits as data  
 on list.dtadmission between data.dtadmission and DATEADD(DD,6,data.dtadmission) group by list.dtadmission
编辑:我没有足够的评论空间来回答您的问题:

我的联接是“有点笛卡尔式的”,因为它在联接约束中使用了一个中间值。列表中的每个记录都与其他记录相对应,然后我想要那些我报告的日期介于下限(-7)之间的记录天和今天。每个数据日期都可用于列表日期,这是您问题的关键。我可以将连接条件写成

list.dtadmission between DATEADD(DD,-6,data.dtadmission) and data.dtadmission
但真正发生的是我把它测试为

list.dtadmission between DATEADD(DD,6,data.dtadmission) and data.dtadmission
它不返回任何记录,因为语法是“介于低和高之间”。我在0条记录上进行了facepalm并交换了参数,仅此而已

尝试以下操作,了解我的意思:这是一个listdate的笛卡尔连接:

 SELECT 
 list.[dtAdmission] as listdate
 ,data.[dtAdmission] as datadate
 ,data.nVisits as datadata
 ,DATEADD(dd,6,list.dtadmission) as listplus6 
 ,DATEADD(dd,6,data.dtAdmission ) as datapplus6 
 from  [sandbox].[dbo].[admAvg] as list inner join [sandbox].[dbo].[admAvg] as data    
 on 
 1=1
 where list.dtAdmission = '5-Jan-2011'
将其与实际连接条件进行比较

 SELECT 
      list.[dtAdmission] as listdate
      ,data.[dtAdmission] as datadate
      ,data.nVisits as datadata
      ,DATEADD(dd,6,list.dtadmission) as listplus6 
      ,DATEADD(dd,6,data.dtAdmission ) as datapplus6
from  [sandbox].[dbo].[admAvg] as list   inner join [sandbox].[dbo].[admAvg] as data    
on 
list.dtadmission between data.dtadmission and DATEADD(DD,6,data.dtadmission)
where list.dtAdmission = '5-Jan-2011'

查看列表日期在所有记录中是如何介于datadate和dataplus6之间的?

是的,很抱歉,该查询中的硬编码日期范围以及其他一些内容只是为了给出一个概念/用于测试目的,而实际函数中有用于这些的变量。我会尝试一下!您能解释一下这是如何实现的吗前几天加上当天?我知道它可以做到这一点,但当我看到它时,我认为它是前6天,因为DATEADD功能非常感谢:D我希望我可以投票不止一次!
 SELECT 
 list.[dtAdmission] as listdate
 ,data.[dtAdmission] as datadate
 ,data.nVisits as datadata
 ,DATEADD(dd,6,list.dtadmission) as listplus6 
 ,DATEADD(dd,6,data.dtAdmission ) as datapplus6 
 from  [sandbox].[dbo].[admAvg] as list inner join [sandbox].[dbo].[admAvg] as data    
 on 
 1=1
 where list.dtAdmission = '5-Jan-2011'
 SELECT 
      list.[dtAdmission] as listdate
      ,data.[dtAdmission] as datadate
      ,data.nVisits as datadata
      ,DATEADD(dd,6,list.dtadmission) as listplus6 
      ,DATEADD(dd,6,data.dtAdmission ) as datapplus6
from  [sandbox].[dbo].[admAvg] as list   inner join [sandbox].[dbo].[admAvg] as data    
on 
list.dtadmission between data.dtadmission and DATEADD(DD,6,data.dtadmission)
where list.dtAdmission = '5-Jan-2011'