SQL Select-Anweisung zum Berechnen einer Spalte für den laufenden Durchschnitt

7

Ich versuche, eine laufende Durchschnittspalte in der SELECT-Anweisung basierend auf einer Spalte aus den n vorherigen Zeilen in derselben SELECT-Anweisung zu haben. Der Durchschnitt, den ich brauche, basiert auf den n vorherigen Zeilen im Resultset.

Lassen Sie mich erklären

%Vor%

Die ersten drei Zeilen der Spalte "Average" sind null, weil keine vorherigen Zeilen vorhanden sind. Die Zeile 4 in der Spalte Durchschnitt zeigt den Durchschnitt der Spalte Anzahl aus den vorherigen 3 Zeilen an.

Ich brauche Hilfe beim Versuch, eine SQL Select-Anweisung zu erstellen, die dies tut.

    
HYP 26.05.2009, 15:32
quelle

7 Antworten

11

Das sollte es tun:

%Vor%     
Aaron Alton 26.05.2009, 15:54
quelle
8

Angenommen, die ID-Spalte ist sequenziell, folgt eine vereinfachte Abfrage für eine Tabelle namens "MyTable":

%Vor%     
ichiban 26.05.2009 16:51
quelle
2

Ein einfacher Self-Join scheint viel besser zu funktionieren als eine Zeile, die auf die Unterabfrage verweist

Erzeuge 10k Reihen von Testdaten:

%Vor%

Ich würde den Spezialfall der ersten drei Zeilen aus der Hauptabfrage ziehen, Sie können ALLE, die zurück in die Reihe gehen, UNION, wenn Sie es wirklich in der Reihe wollen. Self-Join-Abfrage:

%Vor%

Auf meinem Rechner dauert das ungefähr 10 Sekunden, der Unterabfrageansatz, den Aaron Alton demonstriert hat, dauert etwa 45 Sekunden (nachdem ich ihn so geändert habe, dass er meine Testquellentabelle widerspiegelt):

%Vor%

Wenn Sie ein SET STATISTICS PROFILE ON ausführen, können Sie sehen, dass der Self-Join 10k auf dem Tabellen-Spool ausführt. Die Unterabfrage hat 10k, die auf dem Filter, Aggregat und anderen Schritten ausgeführt werden.

    
ahains 26.05.2009 20:04
quelle
1

Edit: Ich habe den Punkt verpasst, dass es die drei vorherigen Datensätze mitteln sollte ...

Für einen allgemeinen laufenden Durchschnitt, denke ich, würde so etwas funktionieren:

%Vor%     
richardtallent 26.05.2009 15:55
quelle
0

Sehen Sie sich einige Lösungen hier an. Ich bin sicher, dass Sie eine von ihnen leicht genug anpassen können.

    
Tom H 26.05.2009 15:38
quelle
0

Wenn Sie möchten, dass dies wirklich performant ist und Sie keine Angst haben, in einen selten genutzten Bereich von SQL Server einzutauchen, sollten Sie sich damit beschäftigen, eine benutzerdefinierte Aggregatfunktion zu schreiben. SQL Server 2005 und 2008 haben die CLR-Integration in die Tabelle integriert, einschließlich der Möglichkeit, Benutzeraggregatfunktionen zu schreiben. Ein benutzerdefiniertes laufendes Gesamtaggregat wäre der effizienteste Weg, um einen laufenden Durchschnitt wie diesen zu berechnen.

    
jrista 26.05.2009 16:06
quelle
0

Alternativ können Sie vorberechnete Laufwerte denormalisieren und speichern. Beschrieben hier:

Ссылка

Die Leistung von selects ist so schnell wie es geht. Natürlich sind Änderungen langsamer.

    
A-K 26.05.2009 18:43
quelle