如何在查询中将数量从一个表分配到另一个表?例如根据实际订单商品数量挑选订单商品数量

时间:2014-08-01 17:05:17

标签: sql sql-server sql-server-2008

我正在订购订单,然后选择订单。订单商品的数量始终为1 - 例如如果同一产品的订单中有两个商品,则会有两行。它们存储在OrderItems表中。订单商品按产品挑选并存储在PickedItems表中,即

CREATE TABLE OrderItems
(
  OrderID int,
  Reference int,
  ProductCode varchar(20),
  Quantity int
);

CREATE TABLE PickedItems
(
  OrderID int,
  ProductCode varchar(20),
  Quantity int,
  Location varchar(20) DEFAULT NULL 
);

例如,以下插入创建了一个包含6个订单项的订单,其中3个用于同一产品,另外2个用于不同的产品,最后是第3个产品的单行。

INSERT INTO OrderItems VALUES (1, 1, 'BOOK', 1);
INSERT INTO OrderItems VALUES (1, 2, 'BOOK', 1);
INSERT INTO OrderItems VALUES (1, 3, 'BOOK', 1);
INSERT INTO OrderItems VALUES (1, 4, 'PEN', 1);
INSERT INTO OrderItems VALUES (1, 5, 'PEN', 1);
INSERT INTO OrderItems VALUES (1, 6, 'CHAIR', 1);

如果选择了2个产品“BOOK”和1个产品“CHAIR”,那么以下内容将在PickedItems表中创建这些条目:

INSERT INTO PickedItems (OrderID, ProductCode, Quantity) VALUES (1, 'BOOK', 2);
INSERT INTO PickedItems (OrderID, ProductCode, Quantity) VALUES (1, 'CHAIR', 1);

以下查询目前用于查找已成功选择的订单商品:

SELECT 
    OrderItems.Reference,
    OrderItems.ProductCode,
    OrderItems.Quantity,
    CASE
        WHEN SUM(OrderItemsCumulative.Quantity) <= PickedItems.Quantity THEN 1
        WHEN (SUM(OrderItemsCumulative.Quantity) - 1) < PickedItems.Quantity THEN PickedItems.Quantity - (SUM(OrderItemsCumulative.Quantity) - 1)
        ELSE 0
    END AS QuantityPicked
FROM
    OrderItems INNER JOIN
    OrderItems OrderItemsCumulative ON (OrderItems.OrderID = OrderItemsCumulative.OrderID) AND (OrderItems.ProductCode = OrderItemsCumulative.ProductCode) AND (OrderItems.Reference >= OrderItemsCumulative.Reference) LEFT JOIN
    PickedItems ON (OrderItems.OrderID = OrderItemsCumulative.OrderID) AND (OrderItems.ProductCode = PickedItems.ProductCode)
WHERE
    OrderItems.OrderID = 1
GROUP BY
    OrderItems.Reference,
    OrderItems.ProductCode,
    OrderItems.Quantity,
    PickedItems.Quantity

这一切都运行正常,但我想扩展它,以便PickedItems可能有多个与之关联的位置(使用PickedItems表中的Location列),因此可能有多个条目/产品的条目在PickedItems表中,例如在“位置A”挑选的2本书和在“位置B”挑选的1本书,将有以下条目。

INSERT INTO PickedItems (OrderID, ProductCode, Quantity, Location) VALUES (1, 'BOOK', 2, 'Location A');
INSERT INTO PickedItems (OrderID, ProductCode, Quantity, Location) VALUES (1, 'BOOK', 1, 'Location B');

因此上面的查询并未考虑该位置。

理想情况下,我希望在上面的场景中返回以下内容,但我似乎无法使其符合查询。我是否最好使用存储过程重写查询并单独分配数据?

+-----------+-------------+-----------------+----------------+------------+
| Reference | ProductCode | QuantityOrdered | QuantityPicked |  Location  |
+-----------+-------------+-----------------+----------------+------------+
|         1 | Book        |               1 |              1 | Location A |
|         2 | Book        |               1 |              1 | Location A |
|         3 | Book        |               1 |              1 | Location B |
|         4 | Pen         |               1 |              0 | NULL       |
|         5 | Pen         |               1 |              0 | NULL       |
|         6 | Chair       |               1 |              0 | NULL       |
+-----------+-------------+-----------------+----------------+------------+

SQL Fiddle

1 个答案:

答案 0 :(得分:1)

理想情况下,您会调整架构以反映更改。

您可能需要通过向订购项添加位置或添加对pickitems的引用来将订单引用与该位置相关联,否则在orderid / productid上始终是笛卡尔因为它们不会是唯一的在任何表中。

使用存储过程,您理论上可以解决笛卡尔问题,但这只会掩盖数据模型的实际问题。