我有一张产品表,其中包含特定日期的销售,购买,开始和结束库存。为简单起见,我在下面的示例中省略了日期和其他产品。我试图使用T-SQL获得产品的平均成本。我对这个问题感到困惑,因为它依赖于之前的记录(天)的AvgCost,它从一开始就是空的。
示例数据
DECLARE @tbl TABLE (Id INT IDENTITY, ProductId INT,
BeginInvt DECIMAL(9,2), SaleQty DECIMAL(9,2), SalePrice DECIMAL(5,3),
PurQty DECIMAL(9,2) NULL, PurCost DECIMAL(5,3) NULL, EndingInvt DECIMAL(9,2))
INSERT @tbl (ProductId, BeginInvt, SaleQty, SalePrice, PurQty, PurCost, EndingInvt )
VALUES
(1,3000,500,2.000,NULL,NULL,2500),
(1,2500,250,2.000,2000,1.800,4250),
(1,4250,300,2.000,NULL,NULL,3950),
(1,3950,900,2.000,4000,1.850,7050),
(1,7050,300,2.000,NULL,NULL,6750),
(1,6750,300,2.000,NULL,NULL,6450),
(1,6450,300,2.000,5000,1.750,11150),
(1,11150,300,2.000,NULL,NULL,10850)
我想获得上述行的AvgCost。鉴于3000件物品的平均成本的初始库存为1.9。解决方案应该有这样的结果
我正在寻找具有AvgCost列的输出,如下所示。该表可以有不同的产品。一旦我有解决方案,我可以应用窗口函数来分区计算。
预期结果
Id ProductId BeginInvt SaleQty SalePrice PurQty PurCost EndingInvt AvgCost
---- ----------- ----------- -------- ---------- --------- -------- ----------- --------
1 1 3000.00 500.00 2.000 NULL NULL 2500.00 1.90000
2 1 2500.00 250.00 2.000 2000.00 1.800 4250.00 1.85556
3 1 4250.00 300.00 2.000 NULL NULL 3950.00 1.85556
4 1 3950.00 900.00 2.000 4000.00 1.850 7050.00 1.85276
5 1 7050.00 300.00 2.000 NULL NULL 6750.00 1.85276
6 1 6750.00 300.00 2.000 NULL NULL 6450.00 1.85276
7 1 6450.00 300.00 2.000 5000.00 1.750 11150.00 1.80789
8 1 11150.00 300.00 2.000 NULL NULL 10850.00 1.80789
可以通过对BeginInvt和Pur值进行加权平均来计算行的AvgCost,如下所示:
((BeginInvt*prevous_day_avgcost)+(PurQty*PurCost))/(BeginInvt+PurQty)
prevous_day_avgcost 对我来说是基于设置的计算的问题
感谢您的帮助...
答案 0 :(得分:1)
使用递归cte的一种方法。这是因为在上一次计算完成之前,您不会知道每行的avgCost。所以你可以迭代地做到这一点。
with rownums as (select t.*,row_number() over(partition by productId order by id) as rnum from @tbl t)
,cte as (select rnum,id,ProductId, BeginInvt, SaleQty, SalePrice,
PurQty, PurCost, EndingInvt ,cast(1.9 as decimal(38,5)) as avgCost --replace this with a calculation if you know it.
from rownums
where rnum=1
union all
select r2.rnum,r2.id,r2.ProductId, r2.BeginInvt, r2.SaleQty, r2.SalePrice, r2.PurQty, r2.PurCost, r2.EndingInvt,
cast(((r2.BeginInvt*r1.avgCost)+(coalesce(r2.PurQty,0)*coalesce(r2.PurCost,0)))/(r2.BeginInvt+coalesce(r2.PurQty,0)) as decimal(38,5))
from cte r1
join rownums r2 on r1.productId=r2.productId and r2.rnum=r1.rnum+1
)
select ProductId, BeginInvt, SaleQty, SalePrice, PurQty, PurCost, EndingInvt, avgCost
from cte