SQL仓库拣货消耗大于数量

SQL仓库拣货消耗大于数量,sql,sql-server,Sql,Sql Server,我把一堆股票分成若干批。一个订单进来了,我们从第一批开始从指定的池中填写该订单。有时,一个订单的数量比一个池中的所有批次都要大,我们需要到另一个池中购买股票 我发现这几乎完全描述了我想要的东西,但答案离我需要数据显示的东西只有一步之遥 样本库存池、批次和数量: +----+------+-----+----------+ | Id | Pool | Lot | Quantity | +----+------+-----+----------+ | 1 | 1 | 1 |

我把一堆股票分成若干批。一个订单进来了,我们从第一批开始从指定的池中填写该订单。有时,一个订单的数量比一个池中的所有批次都要大,我们需要到另一个池中购买股票

我发现这几乎完全描述了我想要的东西,但答案离我需要数据显示的东西只有一步之遥

样本库存池、批次和数量:

+----+------+-----+----------+
| Id | Pool | Lot | Quantity |
+----+------+-----+----------+
|  1 |    1 |   1 |        5 |
|  2 |    1 |   2 |       10 |
|  3 |    1 |   3 |        4 |
|  4 |    2 |   1 |        7 |
|  5 |    3 |   1 |        1 |
|  6 |    3 |   2 |        5 |
+----+------+-----+----------+
订单样本:

+----+------+------------------+
| Id | Pool | QuantityConsumed |
+----+------+------------------+
|  1 |    1 |               17 |
|  2 |    2 |                8 |
|  3 |    3 |                6 |
+----+------+------------------+
使用HABO对链接问题的回答可以得到以下结果:

+------+-----+----------+------------------+-----------------+-----------------+------------------+
| Pool | Lot | Quantity | QuantityConsumed | RunningQuantity | RemainingDemand | SurplusOrDeficit |
+------+-----+----------+------------------+-----------------+-----------------+------------------+
|    1 |   1 |        5 |               17 |               0 |              12 | NULL             |
|    1 |   2 |       10 |               17 |               0 |               2 | NULL             |
|    1 |   3 |        4 |               17 |               2 |               0 | 2                |
|    2 |   1 |        7 |                8 |               0 |               1 | -1               |
|    3 |   1 |        1 |                6 |               0 |               5 | NULL             |
|    3 |   2 |        5 |                6 |               0 |               0 | 0                |
+------+-----+----------+------------------+-----------------+-----------------+------------------+
但是,我希望池2订单然后转到前一个池,如果有盈余,从中提取

最终通缉结果:

+------+-----+----------+------------------+-----------------+-----------------+------------------+
| Pool | Lot | Quantity | QuantityConsumed | RunningQuantity | RemainingDemand | SurplusOrDeficit |
+------+-----+----------+------------------+-----------------+-----------------+------------------+
|    1 |   1 |        5 |               17 |               0 |              12 | NULL             |
|    1 |   2 |       10 |               17 |               0 |               2 | NULL             |
|    1 |   3 |        4 |               17 |               1 |               0 | 1                |
|    2 |   1 |        7 |                8 |               0 |               0 | 0               |
|    3 |   1 |        1 |                6 |               0 |               5 | NULL             |
|    3 |   2 |        5 |                6 |               0 |               0 |  0               |
+------+-----+----------+------------------+-----------------+-----------------+------------------+
我想在link的解决方案之前会有一个临时表strep,其中池订单数量会根据池的可用数量进行检查,但是我不知道如何拆分订单,以便从以前的池中提取所需的额外库存


想法或建议会有帮助。我正在使用SQL Server 2014,但也希望在最新版本的DB2上这样做,因为我们正在转换系统。

我决定直接使用您提供的联接表(称之为
wh
),其中我添加了一个
id
列,原因很明显

create table wh(Id int、Pool int、Lot int、Quantity int、QuantityConsumed int、RunningQuantity int、RemainingDemand int、盈余或赤字int);
去
插入wh值(1,1,1,5,17,0,12,NULL);
插入wh值(2,1,2,10,17,0,2,NULL);
插入wh值(3,1,3,4,17,2,0,2);
插入wh值(4,2,1,7,8,0,1,-1);
插入wh值(5,3,1,1,6,0,7,空);
插入wh值(6,3,2,5,6,0,2,0);
声明@continue int、@d_id int、@s_id int、@deptance int、@max_盈余int;
设置@continue=1;
而@continue=1
开始
--查找第一个赤字池:
从wh中选择@d_id=min(id),其中盈余或赤字<0;
如果@d_id为空
开始
--我们完成了,所有的需求都得到了满足
设置@continue=0;
结束
其他的
开始
从wh中选择@de赤=-盈余或赤字,其中id=@d_id;
--找到第一个池(如果存在),以满足id=@d_id的剩余需求:
从wh中选择@s_id=min(id),其中盈余赤字>=@赤字;
如果@s_id为空
开始
--部分满足最大盈余池的剩余需求:
从盈余或效率>0的wh中选择@max_盈余=max(盈余或效率);
如果@max_盈余不为空
开始
从wh中选择@s_id=min(id),其中盈余或赤字=@max_盈余;
更新wh set PRESSLUSORDEFICIT=0,RUNNINGQUOTE=RUNNINGQUOTE-@max_盈余,其中id=@s_id;
更新wh set PRESSURSORDEFICIT=PRESSURSORDEFICIT+@max_PRESSION,RemainingDemand=RemainingDemand-@max_PRESSION,其中id=@d_id;
结束
其他的
开始
--我们已经做了,有些需求无法满足
设置@continue=0;
结束
结束
其他的
开始
更新wh set RunningQuantity=RunningQuantity-@赤字,盈余Ordeficit=盈余Ordeficit-@赤字,其中id=@s_id;
更新wh set RemainingDemand=0,盈余或赤字=0,其中id=@d_id;
结束
结束
结束
从wh中选择*;

我决定直接使用您提供的联接表(称之为
wh
),出于明显的原因,我在其中添加了一个
id

create table wh(Id int、Pool int、Lot int、Quantity int、QuantityConsumed int、RunningQuantity int、RemainingDemand int、盈余或赤字int);
去
插入wh值(1,1,1,5,17,0,12,NULL);
插入wh值(2,1,2,10,17,0,2,NULL);
插入wh值(3,1,3,4,17,2,0,2);
插入wh值(4,2,1,7,8,0,1,-1);
插入wh值(5,3,1,1,6,0,7,空);
插入wh值(6,3,2,5,6,0,2,0);
声明@continue int、@d_id int、@s_id int、@deptance int、@max_盈余int;
设置@continue=1;
而@continue=1
开始
--查找第一个赤字池:
从wh中选择@d_id=min(id),其中盈余或赤字<0;
如果@d_id为空
开始
--我们完成了,所有的需求都得到了满足
设置@continue=0;
结束
其他的
开始
从wh中选择@de赤=-盈余或赤字,其中id=@d_id;
--找到第一个池(如果存在),以满足id=@d_id的剩余需求:
从wh中选择@s_id=min(id),其中盈余赤字>=@赤字;
如果@s_id为空
开始
--部分满足最大盈余池的剩余需求:
从盈余或效率>0的wh中选择@max_盈余=max(盈余或效率);
如果@max_盈余不为空
开始
从wh中选择@s_id=min(id),其中盈余或赤字=@max_盈余;
更新wh set PRESSLUSORDEFICIT=0,RUNNINGQUOTE=RUNNINGQUOTE-@max_盈余,其中id=@s_id;
更新wh set PRESSURSORDEFICIT=PRESSURSORDEFICIT+@max_PRESSION,RemainingDemand=RemainingDemand-@max_PRESSION,其中id=@d_id;
结束
其他的
开始
--我们已经做了,有些需求无法满足
设置@continue=0;
结束
结束
其他的
开始
更新wh set RunningQuantity=RunningQuantity-@赤字,盈余Ordeficit=盈余Ordeficit-@赤字,其中id=@s_id;
更新wh set RemainingDemand=0,盈余或赤字=0,其中id=@d_id;
结束
结束
结束
从wh中选择*;

我认为消耗的数量必须分成不同的池,以池中的最大数量为上限,或者需要对结果执行另一个递归CTE,其中
create table wh (Id int, Pool int, Lot int, Quantity int, QuantityConsumed int, RunningQuantity int, RemainingDemand int, SurplusOrDeficit int);
GO
insert into wh values (1,1,1,5,17,0,12,NULL);
insert into wh values (2,1,2,10,17,0,2,NULL);
insert into wh values (3,1,3,4,17,2,0,2);
insert into wh values (4,2,1,7,8,0,1,-1);
insert into wh values (5,3,1,1,6,0,7,NULL);
insert into wh values (6,3,2,5,6,0,2,0);

declare @continue int, @d_id int, @s_id int, @deficit int, @max_surplus int;
set @continue = 1;
while @continue = 1
begin
    -- Find the first pool with deficit:
    select @d_id = min(id) from wh where SurplusOrDeficit < 0;
    if @d_id is null
    begin
        -- We are done, all demand has been satisfied
        set @continue = 0;
    end
    else 
    begin
        select @deficit = -SurplusOrDeficit from wh where id = @d_id;
        -- Find the first pool (if such exists) to satisfy the remaining demand for id = @d_id:
        select @s_id = min(id) from wh where SurplusOrDeficit >= @deficit;
        if @s_id is null
        begin
            -- Partially satisfy the remaining demand from a pool which has the biggest surplus:
            select @max_surplus = max(SurplusOrDeficit) from wh where SurplusOrDeficit > 0;
            if @max_surplus is not null
            begin
                select @s_id = min(id) from wh where SurplusOrDeficit = @max_surplus;
                update wh set SurplusOrDeficit = 0, RunningQuantity = RunningQuantity - @max_surplus where id = @s_id;
                update wh set SurplusOrDeficit = SurplusOrDeficit + @max_surplus, RemainingDemand = RemainingDemand - @max_surplus where id = @d_id;
            end
            else
            begin
                -- We are done, some demand cannot be satisfied
                set @continue = 0;
            end
        end
        else
        begin
            update wh set RunningQuantity = RunningQuantity - @deficit, SurplusOrDeficit = SurplusOrDeficit - @deficit where id = @s_id;
            update wh set RemainingDemand = 0, SurplusOrDeficit = 0 where id = @d_id; 
        end
    end
end

select * from wh;