MySQL 在加入 table - 股票 transactions/inventory 系统上获得差异

MySQL get the difference on joined table - stock transactions/inventory system

我不知道怎么问这个问题,但我还是会试试的。我有一个数据库结构,可以跟踪每个产品、产品批次和仓库位置的库存。这让我可以确切地知道哪些产品有库存、价格是多少以及在什么位置。

基本上我使用两个 table 来跟踪

我正在 stock_transactions 中为我们从一个仓库位置移动到另一个位置的每个项目创建一个条目。例如。如果我将 5 件产品 A 从位置 X 移动到位置 y,我将创建两个条目:

INSERT INTO stock_transactions 
(id, product_id, lot_id, warehouse_location_id, type, quantity) 
VALUES (1, 'A', 'Aq2er4', 'X', 'Out', -5)

INSERT INTO stock_transactions 
(id, product_id, lot_id, warehouse_location_id, type, quantity) 
VALUES (1, 'A', 'Aq2er4', 'Y', 'In', 5)

我们通过序列号跟踪一些产品。例如,如果上述产品有序列号,我们将使用条形码 reader 扫描我们已移动到其他位置的产品 A 的哪些序列号。 table stock_transactions_serials 将跟踪每笔股票交易的序列号。

现在我有两个问题需要解决:

1。我需要获取产品清单和库存数量(按 product_id、lot_id 和 location_id 分组。我通过以下方式实现了此目的:

SELECT id, product_id, lot_id, warehouse_location_id, sum(ST.quantity) as qty
FROM stock_transactions ST 
GROUP BY product_id, lot_id, warehouse_location_id
HAVING qty > 0

我在此处使用一些数据创建了 SQLFiddle:http://sqlfiddle.com/#!9/fb352/2

2。我需要获得该库存的正确序列号。我不知道如何解决这个...

如果我加入 tables 我得不到正确的结果,或者我的股票 SUM 是错误的。有任何想法吗?我需要以某种方式区分 In 和 Out 交易之间的差异并获得正确的序列号。

我想你只需要一个 JOIN:

SELECT st.product_id, st.lot_id, st.warehouse_location_id, 
       st.quantity as qty
       GROUP_CONCAT(sts.serial_id) as serials
FROM stock_transactions st JOIN
     stock_transactions_serial sts
     ON sts.stock_transaction_id = st.id
GROUP BY st.product_id, st.lot_id, st.warehouse_location_id, st.quantity
HAVING qty > 0;

注意:这将生成以逗号分隔的序列号列表。

product_id + lot_id + warehouse_location_id 似乎是 stock_transactions 的自然键。您选择添加代理项 id,因此记录通过其自然键或 ID 得到唯一标识。您选择按自然键分组,但您也可以按 id 分组。这个假设是否正确?

在这种情况下,您可以简单地聚合每个 stock_transactions.id 的序列号(即连接它们)并加入此列表:

SELECT
  ST.id, 
  ST.product_id, 
  ST.lot_id, 
  ST.warehouse_location_id, 
  sum(ST.quantity) as qty,
  STS.serials
FROM stock_transactions ST 
LEFT JOIN 
(
  SELECT stock_transaction_id, GROUP_CONCAT(serial_id) AS serials
  FROM stock_transactions_serials
  GROUP by stock_transaction_id
) STS ON STS.stock_transaction_id = ST.id 
GROUP BY ST.product_id, ST.lot_id, ST.warehouse_location_id
HAVING qty > 0;