如何获取两个时间段数据行的差异?——查询后一阶段未销售的产品
解决方法:找出第二个时间段未销售的产品
我明白你的需求啦——你想对比两个时间段的销售数据,找出在第一个时间段有销量,但第二个时间段完全没卖出去的产品,并且把它们的销量显示为0。之前用!=和NOT IN没成功,大概率是因为子查询的构造或者NULL值的影响,我给你两个靠谱的解决方案:
方案一:使用LEFT JOIN + COALESCE
这种方法通过左连接两个时间段的销售数据,筛选出第二个时间段没有匹配记录的产品,并用COALESCE把NULL转换为0:
SELECT t1.product_id, COALESCE(t2.Count, 0) AS Count FROM -- 第一个时间段的销售数据 (SELECT product_id, count(product_id) AS Count FROM testDB WHERE sales_date IS NOT NULL AND delivery_date BETWEEN '2021-02-01 00:00:03.0000000' AND '2021-02-14 23:56:00.0000000' GROUP BY product_id) t1 LEFT JOIN -- 第二个时间段的销售数据 (SELECT product_id, count(product_id) AS Count FROM testDB WHERE sales_date IS NOT NULL AND delivery_date BETWEEN '2021-02-14 00:00:03.0000000' AND '2021-02-28 23:56:00.0000000' GROUP BY product_id) t2 ON t1.product_id = t2.product_id -- 筛选出第二个时间段没有记录的产品 WHERE t2.product_id IS NULL;
原理说明
t1是第一个时间段所有有销量的产品列表,t2是第二个时间段的列表- 左连接后,
t2中没有匹配的产品会显示NULL COALESCE(t2.Count, 0)把NULL替换成0,符合你要的结果格式
方案二:使用NOT EXISTS
如果你更倾向于用存在性判断,这个方法会直接检查第一个时间段的产品在第二个时间段是否有销售记录:
SELECT t1.product_id, 0 AS Count FROM (SELECT product_id, count(product_id) AS Count FROM testDB WHERE sales_date IS NOT NULL AND delivery_date BETWEEN '2021-02-01 00:00:03.0000000' AND '2021-02-14 23:56:00.0000000' GROUP BY product_id) t1 WHERE NOT EXISTS ( -- 检查该产品在第二个时间段是否有销售记录 SELECT 1 FROM testDB t2 WHERE t2.product_id = t1.product_id AND t2.sales_date IS NOT NULL AND t2.delivery_date BETWEEN '2021-02-14 00:00:03.0000000' AND '2021-02-28 23:56:00.0000000' );
原理说明
NOT EXISTS会逐个检查t1中的产品,只要在第二个时间段没有任何符合条件的销售记录,就会被筛选出来- 直接指定
Count为0,省去了处理NULL的步骤
为什么之前的方法没成功?
你提到用!=和NOT IN没得到预期结果,常见原因有两个:
- NOT IN遇到NULL值:如果你的子查询返回的
product_id里有NULL,NOT IN会直接返回空结果(因为SQL中任何值和NULL比较都是未知) - 查询构造问题:如果只是简单对比两个结果集的product_id,可能没有正确关联时间段的筛选条件,导致逻辑出错
这两个方案都能完美解决你的问题,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者Volodymyr Purshega
相关产品推荐
相关产品推荐

