让我们从一个简单的例子开始。有 4 个架子 S1、S2、S3、S4 - 都有 5 件物品的空间。
还有三个托盘 P1(3 个单位)、P2(13 个单位)和 P3(3 个单位)。
很容易想象,最后的结果将是如下所示的货架。
+----+--------+--------+--------+--------+--------+
| | Slot 1 | Slot 2 | Slot 3 | Slot 4 | Slot 5 |
+----+--------+--------+--------+--------+--------+
| S1 | P1 | P1 | P1 | P2 | P2 |
| S2 | P2 | P2 | P2 | P2 | P2 |
| S3 | P2 | P2 | P2 | P2 | P2 |
| S4 | P2 | P3 | P3 | P3 | |
+----+--------+--------+--------+--------+--------+
为了在 SQL 中执行此操作,我在两个表中添加了几个运行总计列。
货架
+----------+------+---------------------+---------------------+
| shelf_id | size | cume size exclusive | cume size inclusive |
+----------+------+---------------------+---------------------+
| S1 | 5 | 0 | 5 |
| S2 | 5 | 5 | 10 |
| S3 | 5 | 10 | 15 |
| S4 | 5 | 15 | 20 |
+----------+------+---------------------+---------------------+
托盘
+------------+------------+---------------------------+---------------------------+
| pallet_id | item count | cume item count exclusive | cume item count inclusive |
+------------+------------+---------------------------+---------------------------+
| P1 | 3 | 0 | 3 |
| P2 | 13 | 3 | 16 |
| P3 | 3 | 16 | 19 |
+------------+------------+---------------------------+---------------------------+
如果
,托盘将(至少部分)放在货架上
- 搁板有空间放置它 - 即搁板(以及之前所有搁板)的容量大于之前所有调色板已使用的空间。
cume size inclusive > cume item count exclusive
- 托盘尚未完全拆包。 - 即所有先前货架的容量小于拆开所有托盘(包括当前托盘)所需的空间。
cume size exclusive < cume item count inclusive
available 可以很容易地计算出来,方法是在托盘完全打开包装后查看货架是否已满,如果是则返回 0,否则返回 cume_size_inclusive - cume_item_count_inclusive。
used 的计算方法是查看托盘物品数量并减去存储在之前或之后货架上的物品。
应该这样做。 Demo
WITH S
AS (SELECT *,
SUM(size) OVER (ORDER BY shelf_id ROWS UNBOUNDED PRECEDING) - size AS cume_shelf_capacity_exclusive,
SUM(size) OVER (ORDER BY shelf_id ROWS UNBOUNDED PRECEDING) AS cume_shelf_capacity_inclusive
FROM #shelves),
P
AS (SELECT *,
SUM(item_count) OVER (ORDER BY pallet_id ROWS UNBOUNDED PRECEDING) - item_count AS cume_items_exclusive,
SUM(item_count) OVER (ORDER BY pallet_id ROWS UNBOUNDED PRECEDING) AS cume_items_inclusive
FROM #palettes)
SELECT S.shelf_id,
S.size,
number_of_items = ISNULL(P.item_count, 0),
used = ISNULL(item_count, 0) - IIF(cume_items_inclusive > cume_shelf_capacity_inclusive, cume_items_inclusive - cume_shelf_capacity_inclusive, 0) --overspill to next shelves
- IIF(cume_shelf_capacity_exclusive > cume_items_exclusive, cume_shelf_capacity_exclusive - cume_items_exclusive, 0), --stocked on previous shelves
available = IIF(cume_shelf_capacity_inclusive < cume_items_inclusive, 0, ISNULL(cume_shelf_capacity_inclusive - cume_items_inclusive, S.size))
FROM S
LEFT JOIN P
ON S.cume_shelf_capacity_inclusive > P.cume_items_exclusive
AND S.cume_shelf_capacity_exclusive < P.cume_items_inclusive
ORDER BY shelf_id,
pallet_id;