I am working on an order management system at the moment where orders are received and then picked. Order items are received with quantity of 1 always - eg if two items are in an order for the same product, there will be two lines. These are stored in the OrderItems table. Order items are picked by product and are stored in the PickedItems table, ie
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
);
So for example the following inserts create an order with 6 line items, 3 of which are for the same product, another 2 for a different product and finally a single line for a 3rd product.
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);
If 2 of the product "BOOK" are picked and 1 of product "CHAIR", then the following will create those entries in the PickedItems table:
INSERT INTO PickedItems (OrderID, ProductCode, Quantity) VALUES (1, 'BOOK', 2);
INSERT INTO PickedItems (OrderID, ProductCode, Quantity) VALUES (1, 'CHAIR', 1);
The following query is currently used to find which Order Items have been picked successfully:
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
This all works fine, but I'd like to extend this so that PickedItems may have multiple locations associated with it (using the Location column in the PickedItems table), and thus there could be more than entry for an Order/Product in the PickedItems table, eg 2 BOOKs picked at "Location A" and 1 BOOK picked at "Location B", would have the following entries.
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');
So the query above isn't taking the location into account.
Ideally I'd want the following returned in the above scenario, but I can't seem to get it fit with the query. Would I be best off rewriting the query using a stored procedure and allocating the data on an individual basis?
+-----------+-------------+-----------------+----------------+------------+
| 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 |
+-----------+-------------+-----------------+----------------+------------+
Ideally you would adapt the schema to reflect the changes.
You may need to relate order reference to the location either by adding location to orderitems, or by adding reference to pickeditems, otherwise there'll always be a Cartesian on orderid/productid because they won't be unique in any of the tables.
With a stored procedure you could in theory work around the Cartesian but that would only mask the actual issue with the data model.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.