我正在使用SQL Server 2012.我有两个表来保存产品订单。具有收到日期的订单和具有价格和订单ID fk的OrderItem。
我有一个查询按日期对订单进行分组,并获取该日期的订单数量和总价格。我还有一个列,显示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 :(得分:0)
我不是100%肯定我理解你的问题,但我相信你在前7天尝试SUM
订单列并除以COUNT
来获取AVG
1}}。如果是这样,那么这应该使用你提供的小提琴:
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
如果您希望那些没有7天数据的记录显示NULL,则检查CASE
的简单COUNT
语句可以确定该值。