Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Fenstergleitender Durchschnitt in SQL Server

Nehmen Sie den hartcodierten Datumsbereich aus Ihrer Abfrage. Schreiben Sie die Ausgabe (wie Ihr Beispiel am Ende) in eine temporäre Tabelle (ich habe sie unten #visits genannt).
Versuchen Sie diese Selbstverknüpfung mit der temporären Tabelle:

 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

BEARBEITEN: Ich hatte nicht genug Platz in den Kommentaren, um Folgendes auf Ihre Frage zu antworten:

Mein Join ist "irgendwie kartesisch", weil er ein Zwischen in der Join-Einschränkung verwendet. Jeder Datensatz in der Liste wird mit jedem anderen Datensatz verglichen, und dann möchte ich diejenigen, bei denen das von mir gemeldete Datum zwischen einer Untergrenze von (-7) Tagen und dem heutigen Tag liegt. Jedes Datendatum ist für das Listendatum verfügbar. Dies ist der Schlüssel zu Ihrer Frage. Ich hätte die Join-Bedingung auch als

schreiben können
list.dtadmission between DATEADD(DD,-6,data.dtadmission) and data.dtadmission

Aber was wirklich passiert ist, ich habe es als

getestet
list.dtadmission between DATEADD(DD,6,data.dtadmission) and data.dtadmission

Was keine Datensätze zurückgibt, da die Syntax "Between LOW and HIGH" ist. Ich habe auf 0 Datensätze gefacepalmed und die Argumente ausgetauscht, das ist alles.

Versuchen Sie Folgendes, verstehen Sie, was ich meine:Dies ist der kartesische Join für nur ein Listendatum:

 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'

Vergleichen Sie dies mit der tatsächlichen Join-Bedingung

 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'

Sehen Sie, wie das Listendatum in allen Datensätzen zwischen datadate und dataplus6 liegt?