2013-03-18 1 views
0

SQL Server 2012를 사용하고 있습니다. 제품 주문을위한 두 개의 테이블이 있습니다. 받은 날짜가있는 주. 및 가격 W 주. ID가있는 OrderItem입니다.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) 

하지만 어떻게해야할지 모르겠습니까? 당신이 볼 수 있듯이

| 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가 마지막 때문에 둘의 평균을 가지고 : 나는 http://sqlfiddle.com/#!6/8b837/44 I는 무엇을 달성하고자하는 내 샘플 데이터에서 그래서

이 같은 결과를 설명하는 데 도움이 sqlfiddle을 만들었습니다 7 일 (25, 24, 23, 22, 18)의 평균은 2입니다.

또한 이것을 확장하고 평균 30 일 이상 다른 열을 추가 할 수 있기를 바랍니다.

도움을 주시면 감사하겠습니다.

답변

0

귀하의 질문에 대한 답변을 100 % 확신하지는 않지만 이전 7 일 동안 SUM 주문 열을보고 으로 나누어 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 일이 가치가없는 레코드의 COUNT을 확인하는 쉬운 CASE 문에 대한 널 (null)을 원하는 경우 그것을 결정할 수 있습니다.