2011-06-28 45 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

对不起,你伤害了我的大脑。如果我可以集中精力试图再次解析这件事情,我会再试一次。 :-) –