2014-09-18 32 views
7

ben (ürün kullanıldığında kaç kez) verilerin saatlik ürün kullanımının bir tablo var - Aynı şekildeSQL sorgusu SQL Server 7 Gün Rolling Ortalama için

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 

, ben 4 farklı ürünler için kullanım verileri var (1 den 4 e kadar ProductId) product_usage tablosunda her saat için saklanır. Tahmin edebileceğiniz gibi, gece ETL süreci bir önceki güne ait verileri döküldüğünde sürekli büyüyor. Bir ürün günün herhangi bir saatinde kullanılmazsa, bu saatteki kayıt bu tabloda görünmez. Benzer şekilde, bir ürün tüm gün boyunca kullanılmazsa, o gün için tabloda herhangi bir kayıt olmaz.

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 

Ve böylece .. Ben SQL server 2014 yılı Endeksli görünümü oluşturmak planlıyorum: Örneğin

- Ben günlük kullanım ve son 7 gün haddeleme ortalamasını veren bir rapor oluşturmak gerekiyor Bunu yapmak için etkili bir SQL sorgusu düşünebilir misiniz?

+0

"Yuvarlama ortalaması" dediğiniz şey gerçekten bir toplam. –

cevap

8

Dene:

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

değiştir "ort üzerinde .... (dailusage)" (daha doğrusu ortalamasına göre) toplamı ile gerçekten ne istediğini eğer geçen haftanın toplamıdır. Başlığınızda ortalamayı istediğinizi söylüyorsunuz ama daha sonra toplamı istediğinizi söylüyorsunuz. Sorgu bundan farklı olmalı, bu yüzden gerçekte istediğinizi kullanın.

Gordon tarafından belirtildiği gibi, temel olarak, ürünün kullanıldığı son 6 tarihin ortalamasıdır, bu, söz konusu ürün için herhangi bir satır içermeyen günler varsa, yalnızca son 6 gündürden fazla olabilir çünkü hiç kullanılmadı. Etrafında dolaşmak için bir tarih tablosunu ve ürünler tablonuzu kullanabilirsiniz. Bazı günlerde veri eksik olabilirseniz dikkatli olmanız gerekir.

+0

Hey, msql 2008 için sql kodunuzu nasıl yeniden yazacağınızı biliyor musunuz? 2008'de çalıştırmayı deniyorum ve hata yapmaya devam ediyorum. –

+1

SQL Server 2008, sözdizimi ARASINDAKİ ROWS'u desteklemiyor. Biraz farklı bir yaklaşıma ihtiyacınız var, örneğin http://stackoverflow.com/questions/26618353/t-sql-calculate-moving-average – reedstonefood

3

Her gün bazı ürünler için veri olduğunu varsayarsak, bu yaklaşım işe yarar:

select p.productid, d.date, sum(usagecount), 
     sum(sum(usagecount)) over (partition by p.productid order by d.date 
            rows between 6 preceding and current row) as Sum7day 
from (select distinct productid from hourly) p cross join 
    (select distinct date from hourly) d left join 
    hourly h 
    on h.productid = p.productid and h.date = p.date 
group by p.productid, d.date;