SQL Server - Как решить FIFO Стоимость OHB… функция, курсор,?
SQL Server 2008 R2 - необходимо решить FIFO стоимость предметов в наличии. Для этого мне нужно добавить стоимость самого последнего количества поступлений до текущего остатка на счете (OHB).
Так скажем, у меня есть
Item : b1234
OHB : 5
Квитанции:
RctNumb | Item | QTYRct | RctCostPerItem | DATERECD
rct05 | b1234 | 1 | 1.00 | 20160822
rct04 | b1234 | 3 | 2.00 | 20160820
rct03 | b1234 | 3 | 1.25 | 20160819
rct02 | b1234 | 2 | 2.50 | 20160818
rct01 | b1234 | 8 | 2.00 | 20160810
Здесь мне понадобится: (1*1,00)+(3*2,00)+(1*1,25) = CostofOHB = 8,25
Я понятия не имею, как решить эту проблему с помощью SQL.
1 ответ
Решение
Я придумал это благодаря подсказкам из других источников. running-totals nested-cursors-w-errors Это очень медленно по сравнению с опцией over(order by) в 2012 году или позже.
DECLARE @FiFo TABLE
(
RctNumb | Item | QTYRct | RctCostPerItem | DATERECD
OHBFIFOCOST decimal(19,5),
OHB decimal(19,5),
SumRctInvcd decimal(19,5),
QtyToCost decimal(19,5),
ITEM nvarchar(65) PRIMARY KEY,
ReportDate [datetime2](0)
);
declare @ITEM as char(31)
declare @OHB as decimal(19,5)
declare @outer_cursor cursor
declare @inner_cursor cursor
declare @RctNumb nvarchar(32)
declare @RCTITEM as nvarchar(65)
declare @QTYRct decimal(19,5)
declare @SumRctInvcd decimal(19,5)
declare @QtyToCost decimal(19,5)
declare @RctCostPerItem decimal(19,5)
declare @OHBCOST decimal(19,5)
declare @OHBrem decimal(19,5)
declare @rowIndex int
declare @DATERECD datetime
declare @fetch_outer_cursor int
declare @fetch_inner_cursor int
set @outer_cursor = cursor static local for
Select
ITEM
,OHB
from ItemMaster
where OHB > 0
/*loop through top level cursor*/
open @outer_cursor
fetch next from @outer_cursor into @ITEM, @OHB
select @fetch_outer_cursor = @@FETCH_STATUS
while @fetch_outer_cursor = 0
begin
/*loop through second level cursor*/
set @inner_cursor = cursor static local for
select
RctNumb
,QTYRct
,RctCostPerItem
,ITEM
,DATERECD
,rowIndex
from RctTbl
Where ITEM = @ITEM
Order By rowIndex desc
open @inner_cursor
fetch next from @inner_cursor into @RctNumb, @QTYRct, @RctCostPerItem, @RCTITEM, @DATERECD, @rowIndex
set @fetch_inner_cursor = @@FETCH_STATUS
while @OHBrem >0 and @fetch_inner_cursor = 0
begin
set @OHBrem = @OHBrem - @QTYRct
set @QtyToCost = case
When @SumRctInvcd + @QTYRct <= @OHB Then @QTYRct
else @OHB - @SumRctInvcd
end
set @OHBCOST = case
When @SumRctInvcd + @QTYRct <= @OHB Then @OHBCOST + (@QtyToCost * @RctCostPerItem)
else @OHBCOST + (@QtyToCost * @RctCostPerItem)
end
set @SumRctInvcd = @SumRctInvcd + @QtyToCost
fetch next from @inner_cursor into @RctNumb, @QTYRct, @RctCostPerItem, @RCTITEM, @DATERECD, @rowIndex
set @fetch_inner_cursor = @@FETCH_STATUS
end
close @inner_cursor
deallocate @inner_cursor
INSERT @FiFo(OHBFIFOCOST, OHB, ITEM, ReportDate, QtyToCost, SumRctInvcd)
SELECT @OHBCOST, @OHB, @ITEM, GETDATE(), @QtyToCost, @SumRctInvcd;
fetch next from @outer_cursor into @ITEM, @OHB
set @fetch_outer_cursor = @@FETCH_STATUS
end
close @outer_cursor
deallocate @outer_cursor
select * from @FiFo