慢动销库存SQL查询报错求助:获取N天未产生销售的库存商品
解决慢动销库存商品查询的SQL问题
嘿,我来帮你搞定这个SQL报错的问题!先看看你原来的SQL里踩的几个坑:
原SQL的问题分析
- 错误的JOIN逻辑:你用了
JOIN来关联库存表和销售表,但JOIN只会保留两边都有匹配的记录,这直接把那些从未被销售过的库存商品过滤掉了,完全不符合你要找“未出现在销售记录里的商品”的需求。 - NOT IN语法错误:你的
WHERE NOT IN(...)缺少了要判断的字段,正确的写法应该是WHERE [字段] NOT IN(...),这里要判断的是库存表的ItemCode。 - 日期范围的小瑕疵:
NOW()会返回当前的日期+时间,而CURDATE()只返回日期,如果saledate是日期类型的话,用CURDATE()作为范围终点更严谨,避免漏掉当天的部分销售记录。
修正后的SQL写法
写法1:使用NOT IN(简洁直观)
SELECT sm.ItemCode FROM db_inventory.StockMain sm WHERE sm.ItemCode NOT IN ( -- 子查询:获取过去90天有销售记录的所有商品ID SELECT si.ItemID FROM db_main.SaleItems si WHERE si.saledate BETWEEN DATE_SUB(CURDATE(), INTERVAL 90 DAY) AND CURDATE() );
我给表起了别名sm(StockMain)和si(SaleItems),让SQL更简洁易读。这个查询的逻辑是:先找出过去90天所有被销售过的商品ID,再从库存表中筛选出不在这个列表里的商品,就是你要的慢动销库存。
写法2:使用LEFT JOIN + IS NULL(更安全)
如果SaleItems.ItemID可能存在NULL值,NOT IN会因为NULL的特性导致结果为空,这时候用LEFT JOIN的方式更可靠:
SELECT sm.ItemCode FROM db_inventory.StockMain sm LEFT JOIN db_main.SaleItems si ON sm.ItemCode = si.ItemID -- 把日期条件放到JOIN的ON子句里,只关联过去90天的销售记录 AND si.saledate BETWEEN DATE_SUB(CURDATE(), INTERVAL 90 DAY) AND CURDATE() -- 筛选出没有匹配到销售记录的库存商品 WHERE si.ItemID IS NULL;
这个写法的逻辑是:保留库存表的所有记录,尝试关联过去90天的销售记录,那些没有匹配到销售记录的行,si.ItemID会是NULL,筛选这些行就得到了目标商品。
额外注意事项
- 确认
StockMain.ItemCode和SaleItems.ItemID的数据类型完全一致(比如都是字符串或都是整数),否则关联会失效。 - 如果
saledate是datetime类型,你可以把CURDATE()换成NOW(),或者用DATE(si.saledate)来统一日期格式,比如:WHERE DATE(si.saledate) BETWEEN DATE_SUB(CURDATE(), INTERVAL 90 DAY) AND CURDATE()
内容的提问来源于stack exchange,提问作者mmdel




