筛选近3个月未售STOCK_ITEMS却返回已售商品的SQL修复问题
问题原因说明
你现有SQL的逻辑是通过内连接关联交易表,且筛选条件直接限定了交易日期为近3个月,查询结果天然只会返回近3个月产生过销售的商品,完全过滤了无销售记录的商品,因此无法满足需求。
修改方案
提供两种常用实现方式,可根据你的场景选择:
方案1:NOT EXISTS子查询(性能更优,推荐)
逻辑为优先匹配全量激活状态的库存商品和客户信息,再排除近3个月产生过对应销售记录的组合:
SELECT DA.ACCNO, DA.NAME, SI.STOCKCODE, SI.DESCRIPTION FROM DR_ACCS DA CROSS JOIN STOCK_ITEMS SI WHERE SI.ISACTIVE = 'Y' -- 排除当前客户+当前商品组合近3个月有销售的记录 AND NOT EXISTS ( SELECT 1 FROM DR_TRANS DT INNER JOIN DR_INVLINES DI ON DT.SEQNO = DI.HDR_SEQNO WHERE DT.ACCNO = DA.ACCNO AND DI.STOCKCODE = SI.STOCKCODE AND DT.TRANSTYPE = 1 AND DI.TRANSDATE > DATEADD(MONTH, -3, GETDATE()) ) ORDER BY DA.NAME
方案2:LEFT JOIN + 空值判断
逻辑为预查询近3个月所有有效销售记录,再左关联全量库存、客户信息,筛选未匹配到销售记录的组合:
SELECT DA.ACCNO, DA.NAME, SI.STOCKCODE, SI.DESCRIPTION FROM DR_ACCS DA CROSS JOIN STOCK_ITEMS SI LEFT JOIN ( SELECT DT.ACCNO, DI.STOCKCODE FROM DR_TRANS DT INNER JOIN DR_INVLINES DI ON DT.SEQNO = DI.HDR_SEQNO WHERE DT.TRANSTYPE = 1 AND DI.TRANSDATE > DATEADD(MONTH, -3, GETDATE()) ) T ON DA.ACCNO = T.ACCNO AND SI.STOCKCODE = T.STOCKCODE WHERE SI.ISACTIVE = 'Y' AND T.ACCNO IS NULL -- 未匹配到近3个月销售记录 ORDER BY DA.NAME
注意事项
- 若你不需要关联客户维度,仅查询全量近3个月无销售的库存商品信息,去掉
DR_ACCS表关联和CROSS JOIN逻辑即可,其余筛选条件可直接复用。 - 若业务中客户和商品有固定对应关系,可在
CROSS JOIN后增加对应过滤条件,减少不必要的计算量。
内容的提问来源于stack exchange,提问作者scyllaSL
相关产品推荐
相关产品推荐

