2014-09-18 9 views
7

ich eine Tabelle mit stündlicher Produktnutzung habe (wie oft das Produkt verwendet wird) Daten -SQL Query für 7 Tage gleitenden Mittelwert in SQL Server

ID (bigint)| ProductId (tinyint)| Date (int - YYYYMMDD) | Hour (tinyint)| UsageCount (int) 
#|1 | 20140901 | 0 | 10 
#|1 | 20140901 | 1 | 15 
#|1 | 20140902 | 5 | 25 
#|1 | 20140903 | 5 | 25 
#|1 | 20140904 | 3 | 25 
#|1 | 20140905 | 7 | 25 
#|1 | 20140906 | 10 | 25 
#|1 | 20140907 | 9 | 25 
#|1 | 20140908 | 5 | 25 
#|2 | 20140903 | 16 | 10 
#|2 | 20140903 | 13 | 115 

Ebenso habe ich die Nutzungsdaten für 4 verschiedene Produkte (ProductId von 1 bis 4) für jede Stunde in der Tabelle product_usage gespeichert. Wie Sie sich vorstellen können, wächst es ständig, da der nächtliche ETL-Prozess die Daten für den gesamten vorherigen Tag ablegt. Wenn ein Produkt zu keiner Stunde eines Tages verwendet wird, wird der Datensatz für diese Stunde nicht in dieser Tabelle angezeigt. Wenn ein Produkt nicht für den gesamten Tag verwendet wird, wird in diesem Fall kein Datensatz für diesen Tag in der Tabelle angezeigt. Ich brauche einen Bericht zu erstellen, die die täglichen Gebrauch und letzten 7 Tage gleitenden Durchschnitt gibt -

Zum Beispiel:

ProductId | Date | DailyUsage | RollingAverage 
1 | 20140901 | sum of usages of that day | (Sum of usages from 20140901 through 20140826)/7 
1 | 20140901 | sum of usages of that day | (Sum of usages from 20140901 through 20140826)/7 
1 | 20140902 | sum of usages of that day | (Sum of usages from 20140902 through 20140827)/7 
2 | 20140902 | sum of usages of that day | (Sum of usages from 20140902 through 20140827)/7 

Und so weiter .. Ich plane, eine indizierte Sicht in SQL Server 2014 erstellen Können Sie sich eine effiziente SQL-Abfrage dazu vorstellen?

+0

Was Sie einen "rollenden Durchschnitt" nennen, ist wirklich eine Summe. –

Antwort

8

Versuchen:

select x.*, 
     avg(dailyusage) over(partition by productid order by productid, date rows between 6 preceding and current row) as rolling_avg 
    from (select productid, date, sum(usagecount) as dailyusage 
      from tbl 
     group by productid, date) x 

Fiddle:

http://sqlfiddle.com/#!6/f674a7/4/0

Ersetzen "avg (dailusage) über ...." mit Summe (statt avg) wenn das, was Sie wirklich wollen ist die Summe für die letzte Woche. In Ihrem Titel sagen Sie, dass Sie den Durchschnitt wollen, aber später sagen Sie, dass Sie die Summe wollen. Die Abfrage sollte die gleiche sein, also verwende, was auch immer du willst. Wie von Gordon aufgezeigt wurde, ist dies im Grunde der Durchschnitt der letzten 6 Daten, in denen das Produkt verwendet wurde, was mehr als nur die letzten 6 Tage sein könnte, wenn es Tage ohne Zeilen für dieses Produkt auf dem Tisch gibt weil es überhaupt nicht benutzt wurde. Um das zu umgehen, können Sie eine Datumstabelle und Ihre Produkttabelle verwenden.

+0

Hey, wissen Sie, wie Sie Ihren SQL-Code für msql 2008 umschreiben? Ich versuche es 2008 und ich bekomme immer Fehler. –

+1

SQL Server 2008 unterstützt keine ROWS BETWEEN-Syntax. Sie benötigen einen etwas anderen Ansatz, zum Beispiel http://stackoverflow.com/questions/26618353/t-sql-calculate-moving-average – reedstonefood

3

Sie müssen vorsichtig sein, wenn an einigen Tagen Daten fehlen können. Wenn ich davon ausgehe, dass an jedem Tag Daten für ein Produkt vorhanden sind, dann wird dieser Ansatz funktionieren: