我有一张表格将客户与以前的购买相关联:
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的人。
我必须创建一个新帐户才能发表评论(我无法使用我昨天创建此帐户的帐户登录,密码恢复说它无法找到我)
答案 0 :(得分:5)
有三种常见方法。这是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效率较低,因为它不会尝试跳过右表中已匹配的值,返回所有结果并将其过滤掉。
来源:
答案 1 :(得分:3)
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)
答案 2 :(得分:1)
有两种不同的方法。
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
答案 3 :(得分:0)
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)