仓库移动建议(合并两个表并填写)- 仅通过 SQL 光标?

Warehouse movements proposal (Combine two tables and fullfill) - Only by SQL Cursor?

我将每个仓库公司的所有产品分成两个数据库 tables(给予者和接受者),并使用某种逻辑为每条记录排序,以按其优先级进行处理。 我最终得到了两个 table。第一个 table 包含付出者,第二个 table 包含接受者

我正在努力创造一个结果,该结果将连续提出从给予者到接受者所需的动作。这只能由 SQL Cursor 处理吗?我可以在不使用 Cursor 的情况下得到结果吗,因为它对我来说很复杂?任何帮助将不胜感激..

捐赠者TABLE

Product QtyAllowedToGive Warehouse_ID_Giver Rank
A 30 100 1
A 30 101 2
A 10 102 3
B 10 200 4
B 6 201 9
D 5 300 10

接受者TABLE

Product QtyAllowedToTake Warehouse_ID_Taker Rank
A 50 200 1
A 5 203 2
A 11 202 3
B 16 202 4
B 3 202 5
C 10 300 6

需要结果

Product QtyToMove Warehouse_ID_Giver Warehouse_ID_Taker
A 30 100 200
A 20 101 200
A 5 101 203
A 5 101 202
A 6 102 202
B 10 200 202
B 9 201 202

也许是这样的?

drop table #Givers
select *
into #Givers
from (values 
 ('A',  30, 100,    1)
,('A',  30, 101,    2)
,('A',  10, 102,    3)
,('B',  10, 200,    4)
,('B',  6,  201,    9)
,('D',  5,  300,    10)
) T(Product,QtyAllowedToGive,   Warehouse_ID_Giver, [Rank])
drop table #Takers
select *
into #Takers
from (values 
 ('A',  50, 200,    1)
,('A',  5,  203,    2)
,('A',  11, 202,    3)
,('B',  16, 202,    4)
,('B',  3,  202,    5)
,('C',  10, 300,    6)
) T(Product,    QtyAllowedToTake,   Warehouse_ID_Taker, [Rank])


declare TakerCursor cursor fast_forward for
   select Product, QtyAllowedToTake, WareHouse_ID_Taker  from #Takers order by  Product, [Rank];
declare GiverCursor cursor fast_forward for
   select Product, QtyAllowedToGive, WareHouse_ID_Giver from #Givers order by Product, [Rank];

declare @TakerProduct char(1)='', @QtyAllowedToTake integer=0, @WareHouseID_Taker integer=0; 
declare @GiverProduct char(1)='', @QtyAllowedToGive integer=0, @WareHouseID_Giver integer=0; 

open TakerCursor
open GiverCursor

fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 return -- no more Takers
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 return -- no more Givers

declare @QtyToMove integer=0
declare @Output table (Product char(1), Warehouse_ID_Giver integer, WareHouse_ID_Taker integer, Qty integer);
while 1=1 begin

  if @TakerProduct=@GiverProduct begin
     if @QtyAllowedToTake<=@QtyAllowedToGive
        set @QtyToMove=@QtyAllowedToTake
     else
       set @QtyToMove=@QtyAllowedToGive 
    
     insert into @Output (Product, Warehouse_ID_Giver, WareHouse_ID_Taker, Qty)
        Select Product=@TakerProduct
              --, QtyAllowedToTake=@QtyAllowedToTake, QtyAllowedToGive=@QtyAllowedToGive, 
              , Giver=@WareHouseID_Giver
              , Taker=@WareHouseID_Taker
              , Qty=@QtyToMove;

     set @QtyAllowedToTake=@QtyAllowedToTake-@QtyToMove
     set @QtyAllowedToGive=@QtyAllowedToGive-@QtyToMove

     if @QtyAllowedToGive=0 begin
         fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
         if @@FETCH_STATUS<>0 break -- no more Givers
     end
     if @QtyAllowedToTake=0 begin
        fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
        if @@FETCH_STATUS<>0 break -- no more Takers
     end
  end else
  if @TakerProduct>@GiverProduct begin
     fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
     if @@FETCH_STATUS<>0 break -- no more Givers
  end else
  if @TakerProduct<@GiverProduct begin
     fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
     if @@FETCH_STATUS<>0 break -- no more Takers
  end
end
close GiverCursor
close TakerCursor
deallocate GiverCursor
deallocate TakerCursor
select * from @Output     

没有错误检查或整理或优化。