[英]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.