Reputation: 357
I have three tables. One consists of customers, one consists of products they have purchased and the last one of the returns they have done:
Table customer
CustID, Name
1, Tom
2, Lisa
3, Fred
Table product
CustID, Item
1, Toaster
1, Breadbox
2, Toaster
3, Toaster
Table Returns
CustID, Date, Reason
1, 2014, Guarantee
2, 2013, Guarantee
2, 2014, Guarantee
3, 2015, Guarantee
I would like to get all the customers that bought a Toaster, unless they also bought a breadbox, but not if they have returned a product more than once.
So I have tried the following:
SELECT * FROM Customer
LEFT JOIN Product ON Customer.CustID=Product.CustID
LEFT JOIN Returns ON Customer.CustID=Returns.CustID
WHERE Item = 'Toaster'
AND Customer.CustID NOT IN (
Select CustID FROM Product Where Item = 'Breadbox'
)
That gives me the ones that have bought a Toaster but not a breadbox. Hence, Lisa and Fred.
But I suspect Lisa to break the products on purpose, so I do not want to include the ones that have returned a product more than once. Hence, what do I add to the statement to only get Freds information?
Upvotes: 0
Views: 55
Reputation: 48197
You use conditional COUNT
SELECT C.CustID, C.Name
FROM Customer C
JOIN ( SELECT CustID
FROM Products
GROUP BY CustID
HAVING COUNT(CASE WHEN Item = 'Toaster' THEN 1 END) > 1
AND COUNT(CASE WHEN item = 'Breadbox' THEN 1 END) = 0
) P -- Get customer with at least one Toaster and not Breadbox
ON C.CustID = P.CustID
JOIN ( SELECT CustID
FROM Returns
HAVING COUNT(*) < 2
) R -- Get only customers with less than 2 returns
ON C.CustID = R.CustID
Upvotes: 0
Reputation: 1406
How about
SELECT * 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'
)
AND (SELECT COUNT(*) FROM Returns WHERE Customer.CustId = Returns.CustID) <= 1
Upvotes: 1
Reputation: 1269873
The filter condition goes in the ON
clause for all but the first table (in a series of LEFT JOIN
:
SELECT *
FROM Customer c LEFT JOIN
Product p
ON c.CustID = p.CustID AND p.Item = 'Toaster' LEFT JOIN
Returns r
ON c.CustID = r.CustID
WHERE c.CustID NOT IN (Select p.CustID FROM Product p Where p.Item = 'Breadbox');
Conditions on the first table remain in the WHERE
clause.
As a note: A table called Product
that contains a CustId
seems awkward. The table behaves more likes its name should CustomerProducts
.
Upvotes: 0