2014-09-18 17 views
7

Tôi có một bảng của việc sử dụng sản phẩm theo giờ (bao nhiêu lần so với sản phẩm được sử dụng) dữ liệu -SQL Query trong vòng 7 ngày cán trung bình trong 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 

Tương tự như vậy, tôi có dữ liệu sử dụng cho 4 sản phẩm khác nhau (ProductId từ 1 đến 4) được lưu trữ cho mỗi giờ trong bảng product_usage. Như bạn có thể tưởng tượng, nó không ngừng phát triển khi quy trình ETL hàng đêm đổ dữ liệu cho toàn bộ ngày hôm trước. Nếu một sản phẩm không được sử dụng vào bất kỳ giờ nào trong ngày, thì bản ghi cho giờ đó sẽ không xuất hiện trong bảng này. Tương tự, nếu sản phẩm không được sử dụng cho cả ngày, sẽ không có bất kỳ bản ghi nào cho ngày đó trong bảng. Tôi cần phải tạo ra một báo cáo cung cấp cho sử dụng hàng ngày và kéo dài trung bình cán 7 ngày -

Ví dụ:

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 

Và vân vân .. Tôi đang lên kế hoạch để tạo ra một chỉ mục Xem trong SQL server 2014 Bạn có thể nghĩ ra một truy vấn SQL hiệu quả để làm điều này không?

+0

Những gì bạn đang gọi là "trung bình cán" thực sự là một khoản tiền. –

Trả lời

8

Hãy thử:

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

Thay thế "trung bình (dailusage) qua ...." với sum (chứ không phải là trung bình) nếu những gì bạn thực sự muốn là tổng của tuần trước. Trong tiêu đề của bạn, bạn nói rằng bạn muốn trung bình nhưng sau đó bạn nói rằng bạn muốn tổng. Truy vấn phải giống nhau, vì vậy hãy sử dụng bất kỳ điều gì bạn thực sự muốn.

Như đã được chỉ ra bởi Gordon, đây là mức trung bình trong 6 ngày qua mà sản phẩm được sử dụng, có thể nhiều hơn 6 ngày qua nếu có ngày không có hàng cho sản phẩm đó trên bàn bởi vì nó không được sử dụng chút nào. Để giải quyết vấn đề đó, bạn có thể sử dụng bảng ngày và bảng sản phẩm của mình.

+0

Hey, bạn có biết cách viết lại mã sql của bạn cho msql 2008 không? Tôi cố gắng chạy nó trong năm 2008 và tôi tiếp tục nhận được lỗi. –

+1

SQL Server 2008 không hỗ trợ cú pháp ROWS BETWEEN. Bạn cần một cách tiếp cận hơi khác, ví dụ: http://stackoverflow.com/questions/26618353/t-sql-calculate-moving-average – reedstonefood

3

Bạn phải cẩn thận nếu bạn có thể thiếu dữ liệu vào một số ngày. Nếu tôi giả định rằng có dữ liệu cho một số sản phẩm vào mỗi ngày, thì cách tiếp cận này sẽ hoạt động:

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; 
Các vấn đề liên quan