2013-03-18 175 views
0

我正在使用SQL Server 2012.我有两个表来保存产品订单。包含接收日期和OrderItem的订单,其中包含价格和订单ID fk。Sql加入平均值

我有一个查询按日期对订单进行分组,并获取该日期的订单数量和总价格。我还有一个7天前的订单数量差异列。

但是,我也希望能够在过去7天内获得所有订单的平均值。

因此,在目前,我有以下查询:

declare @DateFrom datetime 
set @DateFrom = '2012-12-01' 

declare @DateTo datetime 
set @DateTo = '2013-03-13' 

;with orders as (
    select 
    cast(o.ReceivedDate as date) as OrderDate, 
    count(oi.Id) as Orders, 
    coalesce(sum(oi.Price), 0) as Price 
    from OrderItem oi 
    join [Order] o on oi.OrderId = o.Id 
    where cast(o.ReceivedDate as date) >= @DateFrom 
    and cast(o.ReceivedDate as date) <= @DateTo 
    group by cast(o.ReceivedDate as date) 
) 

select c1.OrderDate, 
c1.Price, 
c1.Orders, 
c1.Orders - c2.Orders as DIFF7DAYS 
from orders c1 
left join orders c2 on dateadd(day, -7, c1.OrderDate) = c2.OrderDate 
order by c1.OrderDate desc 

现在我想补充另一列其获得的平均订单在过去的7天。

我已经试过类似:

select c1.OrderDate, 
c1.Price, 
c1.Orders, 
c1.Orders - c2.Orders as DIFF7DAYS, 
c3.AverageOrders 
from orders c1 
left join orders c2 on dateadd(day, -7, c1.OrderDate) = c2.OrderDate 
left join (
select OrderDate, avg(Orders) as AverageOrders 
from orders 
group by OrderDate 
) as c3 on c3.OrderDate >= dateadd(day, -7, c1.OrderDate) and c3.OrderDate <= c1.OrderDate  and c3.OrderDate = c1.OrderDate 
order by c1.OrderDate desc 

但似乎并没有这样做我什么。我也尝试从连接中删除c3.OrderDate = c1.OrderDate,但后来我得到了影响平均值的重复行。基本上我想添加一列到结果:

select avg(Orders) as AverageOrders 
from orders 
where OrderDate >= (the current order - 7 days) and OrderDate <= (the current order) 

但我不知道如何做到这一点?我创建了一个sqlfiddle帮助解释http://sqlfiddle.com/#!6/8b837/44

从我想要实现的是我的样本数据

所以结果是这样的:

| ORDERDATE | ORDERS | PRICE | DIFF7DAYS | AVERAGE | 
------------------------------------------------------- 
| 2013-01-25 |  7 | 38 |   6 |  2 | 
| 2013-01-24 |  2 | 12 |  null |  1 | 
| 2013-01-23 |  1 | 10 |  null |  1 | 
| 2013-01-22 |  1 | 33 |  null | 
| 2013-01-18 |  1 | 10 |  null | 
| 2013-01-10 |  1 |  3 |   -2 | 
| 2013-01-08 |  2 | 11 |  null | 
| 2013-01-04 |  1 |  1 |  null | 
| 2013-01-03 |  3 | 46 |  null | 

正如你可以看到,25日的平均的2因为最后7天(25,24,23,22,18)的四舍五入均值为2.

我也希望能够延长这一点,并为30天以上的平均值添加另一列。

任何帮助将不胜感激。

回答

0

我不是100%正面我理解您的问题,但我相信您正在尝试SUM前7天的订单列,并除以COUNT以获得AVG。如果是这样,那么这应该用你提供的小提琴:

declare @DateFrom datetime 
    set @DateFrom = '2012-12-01' 

    declare @DateTo datetime 
    set @DateTo = '2013-03-13' 

    ;with orders as (
     select 
     cast(o.ReceivedDate as date) as OrderDate, 
     count(oi.Id) as Orders, 
     coalesce(sum(oi.Price), 0) as Price 
     from OrderItem oi 
     join [Order] o on oi.OrderId = o.Id 
     where cast(o.ReceivedDate as date) >= @DateFrom 
     and cast(o.ReceivedDate as date) <= @DateTo 
     group by cast(o.ReceivedDate as date) 
    ), 
    totals as (
     select c1.OrderDate, 
     c1.Price, 
     c1.Orders, 
     c1.Orders - c2.Orders as DIFF7DAYS, 
     ROW_NUMBER() OVER (ORDER BY c1.OrderDate DESC) rn 
     from orders c1 
     left join orders c2 on dateadd(day, -7, c1.OrderDate) = c2.OrderDate 

) 
Select t.OrderDate, t.Price, t.Orders, t.Diff7Days, 
    SUM(t2.Orders)/COUNT(t2.Orders) avg 
FROM totals t 
LEFT JOIN totals t2 on t.rn + 7 > t2.rn and t2.rn >= t.rn 
GROUP BY t.OrderDate, t.Price, t.Orders, t.Diff7Days 
order by t.OrderDate desc 

SQL Fiddle Demo

如果你想为那些不有7天的有价值数据的记录,一个简单的CASE语句来检查COUNT NULL值可以确定。