[英]How to find people who bought one product but NOT another?
我有一个表将客户与以前的购买联系起来:
RecID CustID ProdID
1 20 105
2 20 300
3 31 105
4 45 105
5 45 300
6 45 312
我想获得一个购买第105项的CustID列表,但不是第300项。
在这种情况下, CustID 31。
我似乎无法用选择和连接来做到这一点。 我很难过!
我肯定会感谢有经验的SQL人员提供的一些帮助。
谢谢!
谢谢!
我是这个问题的原作者。
Mark Byers第二个使用NOT IN的例子很棒! (在这个为我工作之后,我没有尝试别人)。
他的第一个LEFT JOIN示例没有返回任何CustID ...我认为我正确地复制了它并使用了正确的表名和列名。 所以我不知道为什么它对我不起作用。
再次感谢所有那些善于花时间为我写出一些SQL的人。
我不得不创建一个新帐户来发表评论(我无法使用我昨天创建的帐户登录,密码恢复说它找不到我)
有三种常见的方法。 这是LEFT JOIN方法:
SELECT T1.CustID
FROM yourtable T1
LEFT JOIN yourtable T2 ON T1.CustID = T2.CustID AND T2.ProdId = 300
WHERE T1.ProdId = 105
AND T2.ProdId IS NULL
这里不是:
SELECT CustID
FROM yourtable
WHERE ProdId = 105
AND CustID NOT IN
(
SELECT CustID
FROM yourtable
WHERE ProdId = 300
)
或者您可以使用NOT EXISTS:
SELECT CustID
FROM yourtable T1
WHERE ProdId = 105
AND NOT EXISTS
(
SELECT NULL
FROM yourtable T2
WHERE T2.ProdId = 300
AND T2.CustID = T1.CustID
)
哪个具有更好的性能取决于您使用的数据库和版本。
对于SQL Server,最好是使用NOT IN或NOT EXISTS:
在SQL Server中,NOT EXISTS和NOT IN谓词是搜索缺失值的最佳方法,只要两个列都是NOT NULL即可。 他们通过某种反加入来制定安全有效的计划。
LEFT JOIN / IS NULL效率较低,因为它不会尝试跳过右表中已匹配的值,返回所有结果并将其过滤掉。
资源:
SELECT CustID from T T1
WHERE ProdID = 105
AND NOT EXISTS (SELECT 1 from T T2
WHERE T2.ProdID = 300
AND T2.CustID = T1.CustID)
几种不同的方法。
select CustID from t where ProdID=105
except
select CustID from t where ProdID=300
要么
select CustID
from t
where ProdID in (105,300)
group by CustID
having max(ProdID)=105
SELECT PPT.CustID FROM PreviousPurchasesTable PPT
WHERE PPT.ProdID = 105
AND PPT.CustID NOT IN (SELECT PPT2.CustID FROM PreviousPurchasesTable PPT2 WHERE PPT2.ProdID = 300)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.