2011-06-28 85 views
0

我有看起來像這樣的數據。SQL查找n行的平均值,其中n是字段的總和

SoldToRetailer

OrderDate | Customer | Product | price | units 
------------------------------------------------- 
1-jun-2011 | customer1 | Product1 | $10 | 5 
2-jun-2011 | customer1 | Product1 | $5 | 3 
3-jun-2011 | customer1 | Product2 | $10 | 4 
4-jun-2011 | customer1 | Product1 | $4 | 4 
5-jun-2011 | customer2 | Product3 | $10 | 1 

SalesByRetailers

Customer | Product | units 
----------------------------- 
customer1 | Product1 | 5 
customer2 | Product3 | 1 

這是我所需要的。

銷售(平均價格)

Customer | Product | units | Average Price 
-------------------------------------------- 
customer1 | Product1 | 5  | $3.44 
customer2 | Product3 | 1  | $10 

平均價格被定義爲平均價格最近SoldToRetailer價格加起來的單位。

因此,在第一種情況下,我從6月4日和6月2日獲取訂單。我不需要(實際上需要)從6月1日起的訂單被包括在內。

編輯:希望更好的解釋。

我試圖確定一個項目被賣給零售商的正確(最近的)價格。這是價格的LIFO訂單。價格是通過平均最近n次訂單的價格來確定的。其中n =特定產品和客戶的零售總額。

在SQL僞代碼看起來像這樣。

Select s1.Customer, s1.product, average(s2.price) 
from SalesByRetailers s1 
join SoldToRetailer s2 
on s1.customer=s2.customer 
and s1.product=s2.product 
and (select top (count of records where s2.units = s1.units) from s2 order by OrderDate desc) 

我需要返回的是來自SoldToRetailer的記錄數量,其中單位總和> = SalesByRetailer單位。

它看起來可以通過RANK或rowover分區來解決,但我很茫然。

SoldToRetailer表格是巨大的,所以性能是非常寶貴的。

運行在SQL 2008R2 感謝您的幫助

+0

「product1總訂單爲9」從哪裏來?單位賣出,單位庫存?什麼是期望的輸出?爲什麼沒有2011年1月1日的product1數據?這不是太清楚... – gbn

+0

編輯以提高清晰度。 9是單位總價和單位庫存。期望的產出是客戶,產品,平均價格。詳細信息記錄日期,因此只返回最近的記錄。 –

+0

你如何達到平均價格3.44?爲什麼你有客戶和訂單的單位? –

回答

1

所以我用3種技術。首先,我創建了一個帶有over by子句的表格,給我一個產品和價格的排序列表,然後編輯表格以添加運行平均值。一個OUTER APPLY子選擇修復了我最後的問題。希望代碼能夠幫助有類似問題的其他人。

向Jeff Moden大聲喊出SQLSderverCentral.com名聲,以表示正在運行的平均幫助。

 SELECT d.ProductKey, 
     d.ActualDollars, 
     d.Units, 
     ROW_NUMBER() OVER(PARTITION BY ProductKey ORDER BY d.OrderDateKey DESC) AS RowNumber, 
     NULL                 AS RunningTotal, 
     CONVERT(DECIMAL(10, 4), 0)           AS RunningDollarsSum, 
     CONVERT(DECIMAL(10, 4), 0)           AS RunningAverage 
    INTO #CustomerOrdersDetails 
    FROM dbo.orders d 
    WHERE customerKey = @CustomerToSelect 

    --DB EDIT... Google "Quirky update SQL Server central. Jeff Moden's version of a 
    --Running total. Holy crap it's faster. tried trangular joins before. 
    CREATE CLUSTERED INDEX [Index1] 
    ON #CustomerOrdersDetails (ProductKey ASC, RowNumber ASC) 

    DECLARE @RunningTotal INT 
    DECLARE @PrevProductKey INT 
    DECLARE @RunningDollarsSum DECIMAL(10, 4) 

    UPDATE #CustomerOrdersDetails 
    SET @RunningTotal = RunningTotal = CASE 
              WHEN ProductKey = @PrevProductKey THEN c.Units + ISNULL(@RunningTotal, 0) 
              ELSE c.Units 
             END, 
     @RunningDollarsSum = RunningDollarsSum = CASE 
                WHEN ProductKey = @PrevProductKey THEN c.ActualDollars + ISNULL(@RunningDollarsSum, 0) 
                ELSE c.ActualDollars 
                END, 
     @PrevProductKey = ProductKey, 
     RunningAverage = @RunningDollarsSum/NULLIF(@RunningTotal, 0) 
    FROM #CustomerOrdersDetails c WITH (TABLOCKX) 
    OPTION (MAXDOP 1) 

    -- ============================================= 
    -- Update Cost fields with average price calculation 
    -- ============================================= 
    UPDATE d 
    SET DolSoldCostUSD = COALESCE(d.DolSoldCostUSD, 
            d.UnitsSold * a.RunningAverage), 
    FROM dbo.inbound d 
     OUTER APPLY (SELECT TOP 1 * 
         FROM #CustomerOrdersDetails ap 
         WHERE ap.ProductKey = d.ProductKey 
          AND d.UnitsSold + d.UnitsOnHand + d.UnitsOnOrder + d.UnitsReceived + d.UnitsReturned >= RunningTotal 
         ORDER BY RunningTotal) AS a 
+0

謝謝你的大喊!我真的很感激它!你的代碼也很棒。 –

+0

只要在信用到期時給予信貸傑夫。我在任何時候開始鍵入CURSOR時仍然聽到RBAR的聲音;-) –

0
declare @table table (customer varchar(15), product varchar(15), qty int, price decimal(6,2)) 

insert into @table (customer, product, qty, price) 
values 
('customer1', 'product1', 5, 3), 
('customer1', 'product1', 4, 4), 
('customer1', 'product1', 3, 2), 
('customer1', 'product1', 2, 13), 
('customer1', 'product1', 3, 3), 

('customer1', 'product2', 5, 1), 
('customer1', 'product2', 4, 7), 
('customer1', 'product2', 2, 5), 
('customer1', 'product2', 6, 23), 
('customer1', 'product2', 2, 1), 

('customer2', 'product1', 2, 1), 
('customer2', 'product1', 4, 4), 
('customer2', 'product1', 7, 3), 
('customer2', 'product1', 1, 12), 
('customer2', 'product1', 2, 3), 

('customer2', 'product2', 3, 2), 
('customer2', 'product2', 6, 5), 
('customer2', 'product2', 8, 4), 
('customer2', 'product2', 2, 11), 
('customer2', 'product2', 1, 2) 

select customer, product, sum(qty) as units, (sum(qty * price))/SUM(qty) as 'Average Price' from @table 
group by customer, product 
+0

在原始代碼中有一個錯誤;這個更新後的代碼可以正確計算一切 –

+0

不解決問題。我不能只是平均價格。我需要根據另一個表格中出售的單位數量進行分組。它也需要容納日期順序。 –

+0

對不起,你傷害了我的大腦。如果我可以集中精力試圖再次解析這件事情,我會再試一次。 :-) –