销售期间的库存计算

时间:2015-02-12 10:08:30

标签: mysql sql

我有一个StockCard表,其中包含以下架构:

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;

目前,当我想销售产品时,我使用LIMIT来了解我是否有足够的left_qty /股票来销售该产品。以下是我的查询,只要for loop仍低于avail_stock,就会在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

我的问题是,通过使用上面的方法,它会改善我的查询性能,还是应该删除LIMIT?随意给出其他方法..

以下是我的问题的简化版:http://sqlfiddle.com/#!9/36ef5

1 个答案:

答案 0 :(得分:1)

不要使用LIMIT,这会产生很多查询。请参阅小提琴here,首先您需要计算之前的总和(请参阅x2minqty)以及之前和当前的总和(请参阅x1或{{1}然后用它们来过滤你需要的东西。

maxqty

例如,当表格包含:15,2和3时,minqty和maxqty将为:

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