2016-03-29 81 views
0

我有两个表。一个由客户和另一个由产品,他们已经购买:选择所有客户,除非他们有其他产品 - SQL

表客户

CustID, Name 
    1,  Tom 
    2,  Lisa 
    3,  Fred 

表产品

CustID, Item 
    1,  Toaster 
    1,  Breadbox 
    2,  Toaster 
    3,  Toaster 

我想获得所有买了一个烤面包机的客户,除非他们还买了一个面包箱。

所以我曾尝试以下:

SELECT * FROM Customer 
JOIN Product 
    ON Customer.CustID=Product.CustID 
WHERE Product in 
    (SELECT 
     Item 
    FROM Product 
    WHERE (Item = 'Toaster' AND Item != 'Breadbox')); 

和:

SELECT * FROM Customer 
INNER Join Product 
ON Customer.CustID=PRODUCT.CustID 
WHERE Product.Item = 'Toaster' 
AND Product.Item NOT IN ('Breadbox'); 

但都给出了相同的结果,其中包括汤姆,这不已经拥有一个面包盒。

我该如何确保只有拥有烤面包机但不拥有面包箱的客户才能上市?

回答

1
SELECT distinct * FROM Customer 
LEFT JOIN Product ON Customer.CustID=Product.CustID 
WHERE Item = 'Toaster' 
AND Customer.CustID NOT IN (
Select CustID FROM Product Where Item = 'Breadbox' 
) 
+0

如果可能的话,此查询将返回没有产品的客户,因此在我看来您想要内连接。如果可能有多个烤面包机,这也会多次列出客户。 – shawnt00

+0

我试过查询,它的工作正确,你能举个例子吗? @ shawnt00 – wajeeh

+0

我的不好。我误解了“where”作为连接条件的一部分。但是,你真的不如写'内部连接',因为这就是你会得到的。 – shawnt00

1

试试这个:

SELECT c.CustID, c.Name 
FROM customer AS c 
JOIN product AS p ON c.CustID = p.CustID 
GROUP BY c.CustID, c.Name 
HAVING SUM(p.Item = 'Toaster') >= 1 AND SUM(p.Item = 'Breadbox') = 0 
2
SELECT * FROM Customer C 
LEFT JOIN Product PT ON C.CustID = PT.CustID AND PT.Item = 'Toaster' 
LEFT JOIN Product PB ON C.CustID = PB.CustID AND PB.Item = 'Breadbox' 
WHERE PT.Item IS NOT NULL AND PB.Item IS NULL 
0
select c.CustID, min(c.Name) as Name 
from Customer c inner join Product p 
    on p.CustID = c.CustID 
where p.Item in ('Toaster', 'Breadbox') 
group by c.CustID 
having 
    max(p.Item) = 'Toaster' and min(p.Item) = 'Toaster' 

having 
     count(case when p.Item = 'Toaster' then 1 end) > 0 
    and count(case when p.Item = 'Breadbox' then 1 end) = 0 

为你做不严格第二种情况需要where虽然它可能有助于在大型演出表。

2

这是我的第一篇文章,所以原谅任何失误。客户和产品表之间存在“多对一”关系。要制定要应用的逻辑限制,您需要汇总产品表格或加入产品表格两次。实际上,您正试图将多对一关系折叠为“一对一”关系。

以下是产品表连接两次的示例。

SELECT DISTINCT 
a.Name 
FROM 
Customer a 
JOIN Product b ON a.CustID = b.CustID 
LEFT JOIN Product c on a.CustID = c.CustID AND c.Item = 'Breadbox' 
WHERE 
b.Item = 'Toaster' AND 
c.CustID IS NULL 

或(略微低效率取决于索引)

SELECT DISTINCT 
a.Name 
FROM 
Customer a 
JOIN Product b ON a.CustID = b.CustID 
WHERE 
b.Item = 'Toaster' AND 
NOT EXISTS (SELECT 1 FROM Product c where a.CustID = c.CustID AND c.Item = 'Breadbox') 

而且,这里是产品表中加入一次的例子 - 可能复杂得多,你需要。

SELECT 
a.Name 
FROM 
Customer a 
JOIN 
(
    SELECT 
    CustID, 
    SUM(case when Item = 'Toaster' then 1 else 0 end) sum_Toaster, 
    SUM(case when Item = 'Breadbox' then 1 else 0 end) sum_Breadbox 
    FROM 
    Product 
    WHERE 
    Item in ('Toaster','Breadbox') 
    GROUP BY 
    CustID 
    HAVING 
    SUM(case when Item = 'Toaster' then 1 else 0 end) > 0 AND 
    SUM(case when Item = 'Breadbox' then 1 else 0 end) = 0 
) b ON a.CustID = b.CustID 
相关问题