我是一个初学者,尝试使用 PHP + SQL 构建非常简单的库存系统
我有2个仓库。我添加了 2 个表,每个仓库 1 个包含 (item id)-(in)-(out) 如下所示
表1
商品编号 | 在 | 出 |
---|---|---|
项目1 | 10 | 0 |
项目1 | 5 | 0 |
项目2 | 0 | 3 |
项目2 | 0 | 2 |
表2
商品编号 | 在 | 出 |
---|---|---|
项目1 | 12 | 0 |
项目1 | 50 | 0 |
项目2 | 0 | 10 |
项目2 | 0 | 30 |
我通过使用下面的查询分别显示每个仓库的余额的报告
Select item_id, sum(in-out) as balance from table1 group by item_id
像下面这样
商品编号 | 平衡 |
---|---|
项目1 | 2 |
项目2 | 20 |
我的问题是如何在一张表中显示每个仓库余额,如下所示
商品编号 | 仓库1 | 仓库2 |
---|---|---|
项目1 | 7 | 2 |
项目2 | 3 | 20 |
我厌倦了这个查询,但得到了错误的结果
SELECT table1.item_id, sum(table1.in)-sum(table1.out) as tb1, sum(table2.in)-sum(table2.out) as tb2 FROM table1 , table2 WHERE table1.item_id=table2.item_id GROUP by item_id
上面的查询有2个问题
只需计算两个表的总和(就像您对第一个表所做的那样),然后将结果连接到 item_id 上。
如果您可以保证两个仓库都具有完全相同的唯一 item_ids 列表,那么您可以执行 INNER JOIN。我假设它们可能存在一些差异,所以我选择了 FULL JOIN。但是,MySQL 似乎不支持 FULL JOIN 选项。所以我采用了 LEFT JOIN 和 RIGHT JOIN 的 UNION 来达到预期的结果。
我用反引号引用了 IN 和 OUT 列,因为 IN 是 SQL 关键字(不确定 OUT,最好是安全起见)。这样它们将被视为列名,而不是它们的其他含义(即 IN 是一个运算符)。
首先,设置一些表来模拟您的数据。
-- Create table corresponding to warehouse 1
DROP TABLE IF EXISTS warehouse1;
CREATE TABLE warehouse1(item_id CHAR(5) NOT NULL
, `in` BIGINT NOT NULL
, `out` BIGINT NOT NULL
);
INSERT INTO warehouse1(item_id
, `in`
, `out`
)
VALUES('item1', 10, 0)
, ('item1', 5, 0)
, ('item2', 0, 3)
, ('item2', 0, 2);
-- Create table corresponding to warehouse 2
CREATE TABLE warehouse2(item_id CHAR(5) NOT NULL
, `in` BIGINT NOT NULL
, `out` BIGINT NOT NULL
);
INSERT INTO warehouse2(item_id
, `in`
, `out`
)
VALUES('item1', 12, 0)
, ('item1', 50, 0)
, ('item2', 0, 10)
, ('item2', 0, 30);
其次,执行聚合并连接结果。
-- Compute the sums for each table, grouped by the item_id and join them together
-- We want a FULL JOIN here. But MySQL doesn't support it, so we UNION a LEFT and a RIGHT
-- to get the same effect.
SELECT wh1.item_id AS item_id
, wh1.balance AS warehouse1_balance
, wh2.balance AS warehouse2_balance
FROM(
SELECT item_id
, SUM(`in` - `out`) AS balance
FROM warehouse1
GROUP BY item_id
) wh1
LEFT JOIN (
SELECT item_id
, SUM(`in` - `out`) AS balance
FROM warehouse2
GROUP BY item_id
) wh2
ON wh1.item_id = wh2.item_id
UNION
SELECT wh2.item_id AS item_id
, wh1.balance AS warehouse1_balance
, wh2.balance AS warehouse2_balance
FROM(
SELECT item_id
, SUM(`in` - `out`) AS balance
FROM warehouse1
GROUP BY item_id
) wh1
RIGHT JOIN (
SELECT item_id
, SUM(`in` - `out`) AS balance
FROM warehouse2
GROUP BY item_id
) wh2
ON wh1.item_id = wh2.item_id
;
我故意使用 UNION 而不是 UNION ALL,因为 LEFT JOIN 和 RIGHT JOIN 都将包含 INNER JOIN。所以我们不想包含两次 INNER JOIN。
自己尝试一下:db<>fiddle