2013-03-18 2 views
0

Я использую SQL Server 2012. У меня есть две таблицы для хранения заказов на продукты. Заказ, который имеет полученную дату и OrderItem, который имеет идентификатор цены и заказа fk.Sql join average

У меня есть запрос, который группирует заказы по дате и получает количество заказов на эту дату и общую цену. У меня также есть столбец для разницы в количестве заказов от 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. Если это так, то это должно работать, используя ваш комплект поставки Fiddle:

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

Если вы хотите NULLs для тех записей, которые не имеют 7 дней стоят данных, легко CASE заявления, чтобы проверить COUNT может определить это.