先用SELECT DISTINCT比对关联字段值,确认映射关系;再统一处理前导零或字母后缀差异;LEFT JOIN后出库量为NULL需检查状态过滤和WHERE误用;核对总量要防明细重复和时间范围不一致;多指标聚合用相关子查询避免GROUP BY冲突。

JOIN 时库存表和出库表的主键对不上怎么办
直接用 product_id 做 JOIN 很容易失败——库存表里是 sku_code,而出库单里可能是 item_no 或 goods_id,字段名不一致只是表象,本质是业务系统没统一编码体系。先用 SELECT DISTINCT 分别查两边的关联字段值,肉眼比对前10条,确认是否真能映射。如果存在前导零差异(比如库存是 '00123',出库是 '123'),得在 JOIN 条件里统一用 TRIM(LPAD(...)) 或 CAST(... AS CHAR) 处理;若一边含字母后缀(如 'A001-RED' vs 'A001'),就得用 SUBSTRING_INDEX 或正则提取基准码。
LEFT JOIN 库存表后发现出库数量为 NULL
这通常不是数据丢了,而是出库记录根本没匹配上库存行——可能该商品从未被录入库存表,或状态字段过滤掉了(比如库存表里 status = 'active',但新上架商品还没更新状态)。检查 JOIN 条件外是否误加了 WHERE 子句:把 WHERE out.stock_date > '2024-01-01' 放在 JOIN 后会把左表没匹配的库存行也过滤掉,正确做法是把这类条件移到 ON 子句里,写成 ON inv.sku = out.item_no AND out.stock_date > '2024-01-01'。另外,确认出库表是否有重复单据号导致笛卡尔积,用 COUNT(*) 和 COUNT(DISTINCT order_no) 对比能快速识别。
核对总量时 SUM 出库量比库存变动大很多
常见原因是出库表存在同一单据的多行明细(比如一个订单拆成三条出库记录),而库存表按 SKU 汇总,直接 SUM(out.qty) 就会重复计算。解决方法是先按 order_no, sku 分组聚合出库量:
SELECT sku, SUM(qty) AS total_out FROM out_log GROUP BY sku,再和库存表 JOIN。另一个坑是时间范围不一致:库存快照取的是“日终”数据,而出库表查的是全天流水,若核对 1 月 1 日库存,出库必须限定
out_time BETWEEN '2024-01-01 00:00:00' AND '2024-01-01 23:59:59',不能只用日期字段做 = '2024-01-01'(多数数据库会忽略时间部分,等价于 >= '2024-01-01')。
需要同时看库存余量和累计出库量,但 GROUP BY 冲突
想在同一结果里显示 inv.current_qty 和 SUM(out.qty),又不想丢失零出库的 SKU,就不能简单 GROUP BY 库存表字段。稳妥做法是两层嵌套:外层 SELECT 库存字段,内层用相关子查询算出库量:
SELECT inv.sku, inv.current_qty, (SELECT COALESCE(SUM(qty), 0) FROM out_log o WHERE o.item_no = inv.sku AND o.out_time <= '2024-01-01') AS total_out FROM inventory inv。如果性能扛不住(出库表超百万行),就把子查询换成 LEFT JOIN + 子查询聚合后的临时表,或者加复合索引
(item_no, out_time)。注意 MySQL 8.0+ 支持窗口函数,但此处不适用——因为要关联不同表,不是同表内分区统计。
真正卡住人的往往不是语法,而是两边系统对“同一商品”的定义粒度不同:库存按规格编码,出库按销售单元,一个 SKU 在出库里可能对应多个 batch_no 或 warehouse_id。核对前得先和业务方确认“什么才算对得上”。

















