如何找到购买一种产品而不是另一种产品的人?

时间:2010-09-10 22:30:59

标签: sql

我有一张表格将客户与以前的购买相关联:

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的人。

我必须创建一个新帐户才能发表评论(我无法使用我昨天创建此帐户的帐户登录,密码恢复说​​它无法找到我)

4 个答案:

答案 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)