我有一个这样的库存分类帐表:
item date time in_qty out_qty in_Price out_Price ABC 01-April-2012 00:00:00 200 750.00 ABC 05-April-2012 00:00:00 100 800.00 ABC 10-April-2012 00:00:00 50 700.00 ABC 16-April-2012 00:00:00 75 800.00 ABC 25-April-2012 00:00:00 175 850.00 XYZ 02-April-2012 00:00:00 150 350.00 XYZ 08-April-2012 00:00:00 120 380.00 XYZ 12-April-2012 00:00:00 80 370.00 XYZ 24-April-2012 00:00:00 80 330.00 XYZ 24-April-2012 00:00:00 90 340.00 LPQ 26-April-2012 00:00:00 70 240.00 LPQ 27-April-2012 00:00:00 30 230.00
我需要FIFO(先进先出)中的每个物料的库存值,这意味着第一个购买的物料应首先消耗。以上数据的输出库存评估为:
Item Qty Value ABC 50 40000 XYZ 110 40500 LPQ 100 23700
请帮助我在FIFO中获得解决方案
我达到了我的期望,
declare @Stock table (item char(3) not null,[date] date not null,[time] time not null,in_qty decimal(18,5) null,out_qty decimal(18,5) null,in_Price decimal(10,2) null,out_Price decimal(10,2) null) insert into @Stock(item , [date] ,[time] , in_qty, out_qty, in_Price,out_Price) values ('ABC','20120401','00:00:00',200 ,0 ,750 ,0), ('ABC','20120401','00:00:00',0 ,100 ,0 ,800), ('ABC','20120401','00:00:00',50 ,0 ,700 ,0), ('ABC','20120401','00:00:00',75 ,0 ,800 ,0), ('ABC','20120401','00:00:00',0 ,175 ,0 ,850), ('XYZ','20120401','00:00:00',150 ,0 ,350 ,0), ('XYZ','20120401','00:00:00',0 ,120 ,0 ,380), ('XYZ','20120401','00:00:00',0 ,80 ,0 ,370), ('XYZ','20120401','00:00:00',80 ,0 ,330 ,0), ('XYZ','20120401','00:00:00',90 ,0 ,340 ,0), ('PQR','20120401','00:00:00',70 ,0 ,240 ,0), ('PQR','20120401','00:00:00',30 ,0 ,230 ,0) ;WITH OrderedIn as ( select *,ROW_NUMBER()OVER (PARTITION BY item ORDER BY date asc,time asc) as S_No from @Stock where in_qty <> 0 ), RunningTotals as ( select item, in_qty, in_Price as price, cast(in_qty as varchar(100)) as Total ,cast(0 as varchar(100)) as PrevTotal,S_No from OrderedIn where S_No = 1 union all select rt.item ,oi.in_qty ,oi.in_Price as price ,cast(rt.Total + oi.in_qty as varchar(100)),cast(rt.Total as varchar(100)),oi.S_No from RunningTotals rt inner join OrderedIn oi on rt.item = oi.item and rt.S_No = oi.S_No - 1 ), TotalOut as ( select item,SUM(out_qty) as Qty from @Stock where out_Price <> 0 group by item ) select rt.item ,SUM(CASE WHEN PrevTotal > COALESCE(out.Qty,0) THEN rt.in_qty ELSE rt.Total - COALESCE(out.Qty,0) END) as Qty ,SUM(CASE WHEN PrevTotal > COALESCE(out.Qty,0) THEN rt.in_qty ELSE rt.Total - COALESCE(out.Qty,0) END * (price)) as Value from RunningTotals rt left join TotalOut out on rt.item = out.item where rt.Total > COALESCE(out.Qty,0) group by rt.item
第一个观察结果是,我们不需要对OUT交易做任何特殊的事情-我们只需要知道总数量即可。这就是TotalOut CTE的计算结果。前两个CTE处理IN事务,并计算每个代表的库存“时间间隔”-更改最终查询以仅从RunningTotals中选择*,以了解这一点。
如果您有单独的日期和时间列,那么您应该先按日期分组,然后再按时间分组。