我有两张桌子。一个由客户组成,另一个由他们购买的产品组成:
表客户
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');
但两者都给出了相同的结果,其中包括已经拥有面包箱的汤姆。
如何确保只有拥有烤面包机但没有面包箱的客户才能上市?
答案 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
答案 1 :(得分:2)
这是我的第一篇文章,原谅任何失误。 Customer和Product表之间存在“多对一”关系。要制定要应用的逻辑限制,您需要聚合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
答案 2 :(得分: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
答案 3 :(得分: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'
)
答案 4 :(得分:0)
having
count(case when p.Item = 'Toaster' then 1 end) > 0
and count(case when p.Item = 'Breadbox' then 1 end) = 0
或
where
对于第二种情况,您并不严格需要{{1}},尽管它可能有助于在大型表上执行。