繁体   English   中英

选择所有客户,除非他们有其他产品-SQL

[英]Select all customers except if they have another product - 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');

但是两者都给出了相同的结果,包括汤姆在内,汤姆已经拥有一个面包箱。

如何确保仅列出拥有烤面包机但不拥有面包箱的客户?

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

这是我的第一篇文章,因此请原谅任何失误。 客户表和产品表之间存在“多对一”关系。 要进行逻辑限制,您将需要汇总Product表或将Product表连接两次。 实际上,您正在尝试将多对一关系折叠为“一对一”关系。

以下是一些示例,其中Product表被连接两次。

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')

而且,这是一个将Product表连接一次的示例-可能比您所需的复杂。

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

尝试这个:

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
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'
)
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虽然它可能有助于提高大型表的性能where但您并不严格要求使用where

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM