如何按不同仓库条件从关联表提取商品的分仓库存数据
解决方案
可以通过三种常见SQL写法完成行转列需求,输出每个商品单条记录、拆分两个仓库的库存字段:
1. 性能最优:条件聚合写法
仅需一次扫描Stores表,无重复关联,是这类固定列转行场景的优先选择:
SELECT p.ProductID, p.Productname, MAX(CASE WHEN s.wharehouse = 1 THEN s.Qty END) AS QtyFromFirstWhareHouse, MAX(CASE WHEN s.wharehouse = 2 THEN s.Qty END) AS QtyFromSecondWhareHouse FROM Products p LEFT JOIN Stores s ON p.ProductID = s.ProductID GROUP BY p.ProductID, p.Productname
因为每个商品在单个仓库仅对应1条库存记录,用MAX聚合不会造成数据错误,还能自动兼容某商品在某仓库无库存的场景(对应字段返回NULL)。
2. 匹配你之前思路的独立子查询写法
你之前尝试独立子查询的实现时,缺失两个必要的筛选/关联逻辑:
- 子查询需要和外层Products表通过ProductID做关联匹配,避免全表取数
- 子查询需要指定对应仓库编号的过滤条件,精准匹配对应仓库的库存
完整可运行的写法如下:
SELECT p.ProductID, p.Productname, (SELECT s.Qty FROM Stores s WHERE s.ProductID = p.ProductID AND s.wharehouse = 1) AS QtyFromFirstWhareHouse, (SELECT s.Qty FROM Stores s WHERE s.ProductID = p.ProductID AND s.wharehouse = 2) AS QtyFromSecondWhareHouse FROM Products p
3. 低学习成本的多次左关联写法
把Stores表按仓库编号过滤后,分别和Products表做左关联,写法更直观:
SELECT p.ProductID, p.Productname, COALESCE(s1.Qty, 0) AS QtyFromFirstWhareHouse, COALESCE(s2.Qty, 0) AS QtyFromSecondWhareHouse FROM Products p LEFT JOIN Stores s1 ON p.ProductID = s1.ProductID AND s1.wharehouse = 1 LEFT JOIN Stores s2 ON p.ProductID = s2.ProductID AND s2.wharehouse = 2
注意:使用左关联写法时,仓库编号的过滤条件必须放在JOIN的ON子句中,不能放到WHERE子句中——否则左关联会退化为内连接,把某仓库无库存的商品直接过滤掉,无法输出完整的商品列表。
如果需要将空值的库存替换为0,可以用COALESCE(库存字段, 0)包裹对应输出列。
内容的提问来源于stack exchange,提问作者Ruby Kousinovali
相关产品推荐
相关产品推荐

