没有while循环或游标

时间:2017-03-02 07:32:00

标签: sql sql-server tsql

我在桌子下面

BoxID   StockPoint  InventoryMasterID   Qty  HoldQty    AvailableQty
    7         UK                   21     3      3            0
    8         UK                   22     2      1            1
    9         UK                   23     4    NULL           4
   10         UK                   24     2    NULL           2

此表包含有关我的股票的信息。

现在我需要从AvailableQty中提取总共3个数量,并且它应该显示一个新列作为PickQty,它应该根据我的RequiredQty(3)显示数量,如果它已满,那么它应该显示为0盒子。

我想把下面的表放在外面。

BoxID   StockPoint  InventoryMasterID   Qty  HoldQty    AvailableQty  PickQty
 7         UK                   21         3      3            0           0
 8         UK                   22         2      1            1           1
 9         UK                   23         4    NULL           4           2
10         UK                   24         2    NULL           2           0  

所以现在我将获取所有那些'PickQty>行0'

我想要这个结果而不使用while循环

1 个答案:

答案 0 :(得分:0)

我在这里发布T-SQL中的分步答案;我相信其他SQL风格很容易从中得出。

可以找到功能演示here

基本查询

解决方案的基本构造是以下查询:

    select 
    a.*, 
   (select sum(coalesce(AvailableQty,0)) 
        from stock b 
        where b.BoxID <= a.BoxID
    ) as cumulative_availability
    from stock a

BoxID   Qty HoldQty AvailableQty    cumulative_availability
7       3       3       0               0 
8       2       1       1               1   
9       4       NULL    4               5
10      2       NULL    2               7

我们应该选择哪些方框?

cumulative_availability包含BoxID <= ID of current box所有框的可用数量的累计和。从这里可以很容易地找到我们应该走多远:

declare @demand int = 3;

declare @stopID int;

select @stopID = min(BoxID) from (
select 
    a.*, 
    (select sum(coalesce(AvailableQty,0)) 
     from stock b 
     where b.BoxID <= a.BoxID
    ) as cumulative_availability
from stock a
) temp
where cumulative_availability >= @demand;

select @stopID;

如果@demand = 3此语句返回9,那么我们需要使用id = 9的方框来满足需求。另一方面,如果@demand = 10,则我们没有足够的资源,而@stopID将是NULL

最后一步

现在计算PickQty列相对容易:

select 
    temp.*, 
    case 
        when cumulative_availability < @demand then AvailableQty 
        else @demand - (cumulative_availability - AvailableQty)
    end 
    as PickQty
from 
(select 
    a.*, 
    (select sum(coalesce(AvailableQty,0)) 
    from stock b 
    where b.BoxID <= a.BoxID
    ) as cumulative_availability
from stock a
) temp
where BoxID <= @stopID or @stopID is null

如果需求过高,or @stopID is null条件可以保证我们能够使用所有方框。