我正在尝试创建一个MS SQL 2005存储过程,以便从仓库为订单中的特定组件分配库存。有多批库存可供使用,必须按特定顺序使用。我可以遍历可用的股票并分配,直到订单完成,但我试图考虑更多基于顺序的集合,并避免使用CURSOR。
这是我的查询,它可以获取特定订单组件的仓库库存;
SELECT
STOCK.ComponentId,
STOCK.StockId,
STOCK.ExpiryDate,
STOCK.BatchNo,
STOCK.StockQty,
ORDER_ITEMS.OrderQty
FROM
STOCK
JOIN ORDER_ITEMS ON ORDER_ITEMS.ComponentId = STOCK.ComponentId
WHERE
STOCK.WarehouseId = @WarehouseId
AND STOCK.StockQty > 0
AND ORDER_ITEMS.OrderItemId = @OrderItemId
我一直把它放到临时表中或者用查询创建一个CTE并应用ORDER BY子句来获取需要用完的库存。这给了我一个结果集:
ComponentId | StockId | ExpiryDate | BatchNo | StockQty | OrderQty
-------------------------------------------------------------------
359 | 3107 | 2013-10-01 | 132435-1 | 20 | 50
359 | 3215 | 2013-10-01 | 154558-1 | 100 | 50
359 | 3216 | 2014-01-01 | 154689-1 | 100 | 50
我需要做的是使用尽可能多的批次库存将记录插入STOCK_ALLOCATED
表中以完成订单数量。在上面的例子中,我将使用第一行中的所有20,然后从第二行需要30。
这需要在STOCK_ALLOCATED
表中插入两个记录,其中OrderItemId
,StockId
和两个批次的数量(20和30)也会减少库存数量适当地在STOCK
表中。
假设有必要的交易以保持库存表的一致性,有一种方法可以进行插入和更新,而无需使用CURSOR循环并跟踪我已经分配了多少库存以及我还需要多少库存?
答案 0 :(得分:2)
这是一个适合您的测试样本:
SELECT
StockID,
Quantity
FROM (
SELECT
StockID,
CASE
WHEN OrderQty - PreviousQty <= 0 THEN 0
ELSE
CASE
WHEN OrderQty - PreviousQty <= Stock
THEN OrderQty - PreviousQty
ELSE
Stock
END
END Quantity
FROM (
SELECT
a.StockID,
a.Stock,
a.OrderQty,
a.OrderByField,
ISNULL(SUM(b.Stock), 0) PreviousQty
FROM
@Table a
LEFT JOIN @Table b ON a.OrderByField > b.OrderByField
GROUP BY a.StockID,
a.Stock,
a.OrderQty,
a.OrderByField
) Orders
) Orders
WHERE Quantity > 0
基本上,您需要加入自己获得的结果,这样您就可以对先前保留数量的数量求和,然后从StockQty中减去它,以确定您仍需要实现的结果。
但是,为了做到这一点,您需要一个唯一的OrderByField,以便您可以准确地过滤掉以前的StockQty值。如果您没有可以使用的存储值,则可以使用ROW_NUMBER() OVER
派生它。如果是这种情况,请告诉我您是否需要帮助。