Reputation: 7288
I have a StockCard
table with below schema:
create table StockCard(
id int(9) zerofill primary key auto_increment,
ref_page smallint(3) not null,
ref_number int(9) not null,
sur_key int unsigned null,
description varchar(255),
warehouse_product_id int(9) zerofill not null,
sc_date datetime not null,
qty int not null,
price double(15,2) not null,
reserved_qty int not null,
left_qty int not null,
status boolean not null, /* true = buy, false = sell*/
CONSTRAINT FOREIGN KEY (warehouse_product_id) REFERENCES Warehouse_Product(id),
CONSTRAINT FOREIGN KEY (ref_page) REFERENCES Page(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
For now, when I want to sell a product I use LIMIT
to know whether I got enough left_qty
/stock for selling that product. Below is my query, which runs in a for loop
as long as avail_stock
still below ordered_qty
:
SELECT SUM(StockCard.left_qty) AS avail_qty FROM StockCard
LEFT JOIN Warehouse_Product ON Warehouse_Product.id = StockCard.warehouse_product_id
WHERE Warehouse_Product.product_id = {product_id}
AND StockCard.status = 1 AND left_qty > 0
ORDER BY sc_date ASC, id ASC
LIMIT {row_limit}
//this row_limit will increase in every loop as long as the SUM smaller than the ordered qty
My question here, is it true that by using my approach above it will improve my query performance or should I just delete the LIMIT
? Feel free to give other approach..
Here is the simplified version of my issue: http://sqlfiddle.com/#!9/36ef5
Upvotes: 1
Views: 119
Reputation: 26818
Don't use LIMIT
, it would be a lot of queries generated. See the fiddle here, first you need to calculate the sum of previous (see x2
or minqty
) and sum of previous and current (see x1
or maxqty
) then use them to filter what you need.
SELECT x3.*
FROM
( SELECT sc1.*, IFNULL(SUM(sc2.left_qty),0) maxqty
FROM StockCard sc1
LEFT JOIN StockCard sc2 ON sc2.id <= sc1.id
WHERE sc1.status = 1 AND sc2.status = 1 AND sc1.warehouse_product_id = 1 AND sc2.warehouse_product_id = 1
GROUP BY sc1.id
ORDER BY sc2.sc_date ASC, sc2.id ASC ) x1
LEFT JOIN
( SELECT sc1.*, IFNULL(SUM(sc2.left_qty),0)+1 minqty
FROM StockCard sc1
LEFT JOIN StockCard sc2 ON sc2.id < sc1.id
WHERE sc1.status = 1 AND sc2.status = 1 AND sc1.warehouse_product_id = 1 AND sc2.warehouse_product_id = 1
GROUP BY sc1.id
ORDER BY sc2.sc_date ASC, sc2.id ASC ) x2
ON x1.id = x2.id
LEFT JOIN StockCard x3 ON x3.id <= x1.id
AND x3.warehouse_product_id = sc1.warehouse_product_id
WHERE IFNULL(x2.minqty,0) <= 15 -- > change these
AND x1.maxqty >= 15 --> change these
For example when the table contains: 15, 2 and 3, minqty and maxqty would be:
qty min max
15 1 15
2 16 17
3 18 21
Upvotes: 1