DECLARE @TC TABLE([AutoID] INT IDENTITY(1,1), [ProductsID] INT, [in_AutoID] INT, [inPrice] DECIMAL(5,2), [inQty] INT, [out_AutoID] INT, [outQty] INT, [Balance] INT)DECLARE @TA TABLE([AutoID] INT, [ProductsID] INT, [inPrice] DECIMAL(5,2), [inQty] INT, [inDate] DATETIME)
INSERT @TA 
SELECT 1, 3310, 3.50, 10, '2005-3-1' UNION ALL 
SELECT 2, 3310, 3.60, 20, '2005-3-8' UNION ALL 
SELECT 3, 3310, 3.70, 25, '2005-3-9'DECLARE @TB TABLE([AutoID] INT, [ProductsID] INT, [outQty] INT, [outDate] DATETIME)
INSERT @TB 
SELECT 1, 3310, 10, '2005-3-10' UNION ALL 
SELECT 2, 3310, 15, '2005-3-11' UNION ALL 
SELECT 3, 3310, 30, '2005-3-12'INSERT @TC([ProductsID],[in_AutoID],[inPrice],[inQty],[out_AutoID],[outQty],[Balance])
SELECT A.[ProductsID],
A.[AutoID],
A.[inPrice],
CASE WHEN B.[outQty]>A.[inQty] THEN [inQty] ELSE [outQty] END,
A.[AutoID],
CASE WHEN B.[outQty]>A.[inQty] THEN [inQty] ELSE [outQty] END,
CASE WHEN B.[outQty]>A.[inQty] THEN 0 ELSE A.[inQty]-B.[outQty] END
FROM @TA AS A JOIN @TB AS B
  ON A.[ProductsID]=B.[ProductsID] AND A.[AutoID]=B.[AutoID]
WHERE A.[AutoID]=1WHILE @@ROWCOUNT>0
BEGIN
  WHILE EXISTS(
  SELECT 1
  FROM (SELECT [ProductsID],SUM([outQty]) AS [outQty] FROM @TB GROUP BY [ProductsID]) A
    JOIN (SELECT [ProductsID],SUM([outQty]) AS [outQty] FROM @TC GROUP BY [ProductsID]) C
      ON A.[ProductsID]=C.[ProductsID] 
      WHERE A.[outQty]<>C.[outQty]
   )
  BEGIN    
    SELECT TOP 1 A.[AutoID],A.[ProductsID],[inPrice],A.[inQty]-ISNULL(C.[inQty],0) AS [inQty] INTO #T1
    FROM @TA AS A LEFT JOIN (SELECT [ProductsID],[in_AutoID],SUM([inQty]) AS [inQty] FROM @TC GROUP BY [ProductsID],[in_AutoID]) AS C 
       ON A.[ProductsID]=C.[ProductsID] AND A.[AutoID]=C.[in_AutoID]
    WHERE A.[inQty]>ISNULL(C.[inQty],0)
    ORDER BY A.[AutoID]    SELECT TOP 1 A.[AutoID],A.[ProductsID],A.[outQty]-ISNULL(C.[outQty],0) AS [outQty] INTO #T2
    FROM @TB AS A LEFT JOIN (SELECT [ProductsID],[out_AutoID],SUM([outQty]) AS [outQty] FROM @TC GROUP BY [ProductsID],[out_AutoID]) AS C 
       ON A.[ProductsID]=C.[ProductsID] AND A.[AutoID]=C.[out_AutoID]
    WHERE A.[outQty]<>ISNULL(C.[outQty],0)
    ORDER BY A.[AutoID]    INSERT @TC([ProductsID],[in_AutoID],[inPrice],[inQty],[out_AutoID],[outQty],[Balance])
SELECT A.[ProductsID],
A.[AutoID],
A.[inPrice],
CASE WHEN B.[outQty]>A.[inQty] THEN [inQty] ELSE [outQty] END,
B.[AutoID],
CASE WHEN B.[outQty]>A.[inQty] THEN [inQty] ELSE [outQty] END,
0
FROM #T1 AS A JOIN #T2 AS B
      ON A.[ProductsID]=B.[ProductsID] 
    
    DROP TABLE #T1,#T2
  END
END
SELECT * FROM @TC
/*
1 3310 1 3.50 10 1 10 0
2 3310 2 3.60 15 2 15 0
3 3310 2 3.60 5 3 5 0
4 3310 3 3.70 25 3 25 0
*/

解决方案 »

  1.   

    alter proc proc_fifo_outmaterialdetail
    as 
    begin 
    declare @id bigint,@inid bigint,@outid bigint,@projectid bigint,@materialid bigint,@priceid bigint,@type varchar(1),@getDate varchar(20)
    declare @incount decimal(18,2),@outcount decimal(18,2),@flag decimal(18,2),@leavecount decimal(18,2),@temp_count decimal(18,2)
    declare c_out cursor for
    select id,projectid,materialid,thiscount from v_fifo_out order by createtimeopen c_out
    fetch NEXT from c_out into @outid,@projectid,@materialid,@outcount
    WHILE   @@FETCH_STATUS=0 
    begin
    set @temp_count = 0
    while @temp_count < @outcount
    begin 
    if exists(select cast(flag as decimal(18,2)) from v_fifo_in where cast(flag as decimal(18,2))> 0 and materialid = @materialid)
    begin 
    select top 1 @id = id,@type = type,@flag = cast(flag as decimal(18,2)),@inid=id,@priceid=price from v_fifo_in where cast(flag as decimal(18,2))> 0 and materialid = @materialid order by createtime
    set @leavecount = @outcount  - @temp_count 
    if @flag - @leavecount >= 0
    begin
    insert into t_fifo_out_materialdetail(createtime,inid,outid,priceid,count) values(getdate(),@inid,@outid,@priceid,@leavecount)
    if @type='1'
    update t_fn_material_warehouse set flag = @flag - @leavecount where id = @id
    if @type ='2'
    update t_fn_orderin_detail set flag = @flag - @leavecount where id = @id
    if @type='3'
    update t_fn_allocationindetail set flag = @flag - @leavecount where id = @id
    if @type='4'
    update t_fn_backwarehouse_detail set flag = @flag - @leavecount where id = @id
    set @temp_count = @temp_count + @leavecount
    end
    else 
    begin
    insert into t_fifo_out_materialdetail(createtime,inid,outid,priceid,count) values(getdate(),@inid,@outid,@priceid,@flag)
    if @type ='1'
    update t_fn_material_warehouse set flag = 0.00 where id = @id
    if @type ='2'
    update t_fn_orderin_detail set flag = 0.00 where id = @id
    if @type='3'
    update t_fn_allocationindetail set flag = 0.00 where id = @id
    if @type='4'
    update t_fn_backwarehouse_detail set flag = 0.00 where id = @id
    set @temp_count = @temp_count + @flag  
    end
    end 

    else 
    begin 
    select top 1 @id = id,@type = type,@incount = thiscount,@inid=id,@priceid=price from v_fifo_in where flag is null and materialid = @materialid order by createtime
    set @leavecount = @outcount  - @temp_count
    if @incount - @leavecount >=0
    begin
    insert into t_fifo_out_materialdetail(createtime,inid,outid,priceid,count) values(getdate(),@inid,@outid,@priceid,@leavecount)
    if @type ='1'
    update t_fn_material_warehouse set flag = @incount - @leavecount where id = @id
    if @type ='2'
    update t_fn_orderin_detail set flag = @incount - @leavecount where id = @id
    if @type='3'
    update t_fn_allocationindetail set flag = @incount - @leavecount where id = @id
    if @type='4'
    update t_fn_backwarehouse_detail set flag = @incount - @leavecount where id = @id

    set @temp_count = @temp_count + @leavecount
    end 
    else
    begin 
    insert into t_fifo_out_materialdetail(createtime,inid,outid,priceid,count) values(getdate(),@inid,@outid,@priceid,@incount)
    if @type ='1'
    update t_fn_material_warehouse set flag = 0 where id = @id
    if @type ='2'
    update t_fn_orderin_detail set flag = 0 where id = @id
    if @type='3'
    update t_fn_allocationindetail set flag = 0 where id = @id
    if @type='4'
    update t_fn_backwarehouse_detail set flag = 0 where id = @id
    set @temp_count = @temp_count + @incount
    end 
    end 
    end 
    fetch NEXT from c_out into @outid,@projectid,@materialid,@outcount
    end
    close c_out
    deallocate c_out
    end 
    go