1

I have a set of order items placed in my table. These order items are generated from 2 order types. The sales order and the purchase order. One sales order can have multiple purchase orders to fulfill the quantities. I want a way to calculate the remaining quantity to fulfill the next sales order in database level.

this is my order table

+----+------------+------------+------------------------+--------+------------+
| id | order_type | order_from | base_order_if_purchase | amount | status     |
+----+------------+------------+------------------------+--------+------------+
| 1  | sales      | 1          | null                   | 8500   | incomplete |
+----+------------+------------+------------------------+--------+------------+
| 2  | purchase   | 1          | 1                      | 2500   | complete   |
+----+------------+------------+------------------------+--------+------------+
| 3  | purchase   | 1          | 1                      | 5000   | complete   |
+----+------------+------------+------------------------+--------+------------+

The sales order will be completed after the quantities has been fulfilled in all purchase orders.

This is my order_items table

+----+----------+---------+----------+--------+
| id | order_id | item_id | quantity | type   |
+----+----------+---------+----------+--------+
| 1  | 1        | 1       | 10       | Accept |
+----+----------+---------+----------+--------+
| 2  | 1        | 2       | 15       | Accept |
+----+----------+---------+----------+--------+
| 3  | 1        | 3       | 20       | Reject |
+----+----------+---------+----------+--------+
| 4  | 2        | 1       | 5        | Accept |
+----+----------+---------+----------+--------+
| 5  | 2        | 2       | 10       | Accept |
+----+----------+---------+----------+--------+
| 6  | 2        | 4       | 10       | Accept |
+----+----------+---------+----------+--------+
| 7  | 3        | 1       | 2        | Accept |
+----+----------+---------+----------+--------+
| 9  | 3        | 2       | 5        | Accept |
+----+----------+---------+----------+--------+

Order 1 is the sales Order. Order 2 & 3 are purchase orders. I want to calculate the remaining quantities of the items. Some new items also can be added in the purchase order which are not in the sales order.

Accepted Order 1 items - (Order 2 items + Order 3 items)

So the result should be

+---------+----------+
| item_id | quantity |
+---------+----------+
| 1       | 3        |
+---------+----------+
| 2       | 0        |
+---------+----------+
| 4       | 10       |
+---------+----------+

I'm currently doing this by selecting the items in each order and performing the calculation in application level.

4
  • 1
    there must be a field/column that marks an order as sell or purchase, or you have a order tbale that holds that information, so you must post that too
    – nbk
    Commented Sep 16, 2020 at 7:50
  • Yes it is stored in order table. I'll post that too.
    – camille
    Commented Sep 16, 2020 at 7:55
  • order table added
    – camille
    Commented Sep 16, 2020 at 8:01
  • 1
    the column order_type should be a Itinint type,and with another table, you would save a lot of space in the long run
    – nbk
    Commented Sep 16, 2020 at 8:04

1 Answer 1

1

you should normalize your tbales the columns order_items.type and orders.order_type should be Tinyint and you need also two small tables ordertype and orderItemtype that canes joined when the text is needed

Schema (MySQL v5.7)

CREATE TABLE order_items (
  `id` INTEGER,
  `order_id` INTEGER,
  `item_id` INTEGER,
  `quantity` INTEGER,
  `type` VARCHAR(6)
);

INSERT INTO order_items
  (`id`, `order_id`, `item_id`, `quantity`, `type`)
VALUES
  ('1', '1', '1', '10', 'Accept'),
  ('2', '1', '2', '15', 'Accept'),
  ('3', '1', '3', '20', 'Reject'),
  ('4', '2', '1', '5', 'Accept'),
  ('5', '2', '2', '10', 'Accept'),
  ('6', '2', '4', '10', 'Accept'),
  ('7', '3', '1', '2', 'Accept'),
  ('9', '3', '2', '5', 'Accept'),
  ('10', '4', '1', '5', 'Accept'),
  ('11', '4', '2', '10', 'Accept');

CREATE TABLE orders (
  `id` INTEGER,
  `order_type` VARCHAR(8),
  `order_from` INTEGER,
  `base_order_if_purchase` VARCHAR(4),
  `amount` INTEGER,
  `status` VARCHAR(10)
);

INSERT INTO orders
  (`id`, `order_type`, `order_from`, `base_order_if_purchase`, `amount`, `status`)
VALUES
  ('1', 'sales', '1', NULL, '8500', 'incomplete'),
  ('2', 'purchase', '1', '1', '2500', 'complete'),
  ('3', 'purchase', '1', '1', '5000', 'complete'),
  ('4', 'sales', '1', NULL, '7000', 'incomplete');

Query #1

SELECT 
    `row_num`,`item_id`
    ,SUM(`sumitem`)
   FROM 
   (SELECT 
         `item_id`,o.`row_num` , IF (`order_type` = 'sales',`quantity`,-`quantity`) sumitem
    FROM order_items o_i 
   INNER JOIN (  SELECT o.`id`, o.`order_type`,row_num
  FROM `orders` o INNER JOIN (
  SELECT `id`, @rn := @rn + 1  row_num FROM orders ,(SELECT @rn := 0) a WHERE `base_order_if_purchase` IS NULL ORDER BY `id`) o1 
  ON o.`id` =  o1.`id` OR o.`base_order_if_purchase` =  o1.`id`) o ON o_i.`order_id` = o.`id`
   WHERE o_i.`type` = 'Accept') t1
  GROUP BY `row_num`,`item_id`;

| row_num | item_id | SUM(`sumitem`) |
| ------- | ------- | -------------- |
| 1       | 1       | 3              |
| 1       | 2       | 0              |
| 1       | 4       | -10            |
| 2       | 1       | 5              |
| 2       | 2       | 10             |

View on DB Fiddle

7
  • Hi. I just run your code. I want the result based on 1 sales order. If there are 2 sales orders this query gives wrong result. I updated the fiddle data. db-fiddle.com/f/4yPorU6k3SjQ5nmhgi1wGo/27
    – camille
    Commented Sep 16, 2020 at 11:55
  • 1
    what should the result be then, please write it as comment also in the fiddle and link it new
    – nbk
    Commented Sep 16, 2020 at 12:32
  • your answer is correct for the 1st sales order (and the 2nd & 3rd purchase orders). If I add another sales order results gonna change. I have commented the lines in the schema (db-fiddle.com/f/4yPorU6k3SjQ5nmhgi1wGo/28). What I meant was the final results (item_id & sum) should be for one sales order.
    – camille
    Commented Sep 16, 2020 at 12:49
  • 1
    For that you need another column to diffrentiate the sales, save it in your table as you can see, in the example, it is quite complcated to get it
    – nbk
    Commented Sep 16, 2020 at 14:45
  • 1
    @camille no problem i changed it to mysql 5-7
    – nbk
    Commented Sep 16, 2020 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.