Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Média móvel da janela no sql server


Retire o intervalo de datas codificado da sua consulta. Escreva a saída (como sua amostra no final) em uma tabela temporária (chamei de #visits abaixo).
Tente esta autojunção na tabela temporária:
 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

EDITAR: Eu não tinha espaço suficiente nos comentários para dizer isso em resposta à sua pergunta:

Minha junção é "meio cartesiana" porque usa um entre na restrição de junção. Cada registro na lista está indo contra todos os outros registros, e então eu quero aqueles em que a data que eu reporto está entre um limite inferior de (-7) dias e hoje. Cada data de dados está disponível para listar data, esta é a chave para sua pergunta. Eu poderia ter escrito a condição de junção como
list.dtadmission between DATEADD(DD,-6,data.dtadmission) and data.dtadmission

Mas o que realmente aconteceu foi que eu testei como
list.dtadmission between DATEADD(DD,6,data.dtadmission) and data.dtadmission

Que não retorna nenhum registro porque a sintaxe é "Entre LOW e HIGH". Eu fiz facepalm em 0 registros e troquei os argumentos, isso é tudo.

Tente o seguinte, veja o que quero dizer:Esta é a junção cartesiana para apenas uma data de lista:
 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'

Compare isso com a condição de junção real
 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'

Veja como a data da lista está entre datadate e dataplus6 em todos os registros?