使用Self-join查询购买某产品但未购买另一产品的CustomerID
问题根因
你编写的SQL核心逻辑错误如下:
- 筛选条件列名误用:将产品ID的匹配条件错误作用在
CustomerID字段上,逻辑完全错位 - 自连接条件逻辑冲突:隐式笛卡尔积连接后,
a.CustomerID和b.CustomerID相等的前提下,不可能同时满足a.CustomerID in ({{ProductID}})和b.CustomerID not in ({{ProductID}}),因此返回结果不符合预期
可行解决方案
假设你需要查询**购买了指定目标产品{{TargetProductID}}、且未购买指定排除产品{{ExcludedProductID}}**的客户ID,可选用以下任意一种方案:
方案1:修正后的自连接写法
SELECT DISTINCT a.CustomerID FROM iread a LEFT JOIN iread b ON a.CustomerID = b.CustomerID AND b.ProductID = {{ExcludedProductID}} WHERE a.ProductID = {{TargetProductID}} AND b.CustomerID IS NULL
逻辑说明:先筛选所有购买了目标产品的客户记录,左连接关联该客户购买排除产品的记录,最终只保留没有匹配到排除产品购买记录的客户ID即可。
方案2:聚合查询写法(数据量大时性能更优)
SELECT CustomerID FROM iread WHERE ProductID IN ({{TargetProductID}}, {{ExcludedProductID}}) GROUP BY CustomerID HAVING MAX(CASE WHEN ProductID = {{TargetProductID}} THEN 1 ELSE 0 END) = 1 AND MAX(CASE WHEN ProductID = {{ExcludedProductID}} THEN 1 ELSE 0 END) = 0
逻辑说明:过滤出所有和目标产品、排除产品相关的购买记录,按客户分组后,筛选出存在目标产品购买记录、且不存在排除产品购买记录的客户即可。
示例验证
以你给出的测试数据为例,若查询「购买了产品5555555,且未购买产品1111111的客户」,两种方案都会返回正确结果17890。
内容的提问来源于stack exchange,提问作者bababababa
相关产品推荐
相关产品推荐

