Reputation: 11
This is my functioning SQL query to return the customers that we sold to in 1996:
SELECT C.CustomerID, C.CompanyName
FROM Customers C, Orders O
WHERE C.CustomerID = O.CustomerID AND YEAR(O.OrderDate) = 1996
GROUP BY C.CustomerID, C.CompanyName
ORDER BY C.CustomerID
Now I'm trying to show the opposite; return all customers that we did not sell to in 1996 (even if we did sell to them in other years). This is what I have, however it returns both the customers we didn't sell to in 1996 but also the ones we did:
SELECT C.CustomerID, C.CompanyName FROM Orders O JOIN Customers C
ON O.CustomerID = C.CustomerID
WHERE YEAR(O.OrderDate) != 1996
GROUP BY C.CustomerID, C.CompanyName
ORDER BY C.CustomerID
Upvotes: 0
Views: 616
Reputation: 222442
We can build on your existing query and use the left join
antipattern:
SELECT C.CustomerID, C.CompanyName
FROM Customers C
LEFT JOIN Orders O
ON C.CustomerID = O.CustomerID
AND O.OrderDate >= '1996-01-01'
AND O.OrderDate < '1997-01-01'
WHERE O.CustomerID IS NULL
ORDER BY C.CustomerID
This phrases as : try to join each customers with the orders they have placed in 1996, and filter on those without any order.
Side note:
always use explicit, standard join (with the ON
keyword); old-school, implicit joins should be avoided (no comma in the FROM
clause)
as also commented by sticky bit (whose answer is valid and I upvoted it), using date comparison is better form performance than relying on date functions
Upvotes: 2
Reputation: 37472
You can use a correlated subquery that gets the orders from 1996 of a customer with NOT EXISTS
.
SELECT c.customerid,
c.companyname
FROM customers c
WHERE NOT EXISTS (SELECT *
FROM orders o
WHERE o.customerid = c.customerid
AND o.orderdate >= '1996-01-01'
AND o.orderdate < '1997-01-01');
Note that you better shouldn't use year()
on orderdate
as this can prevent indexes form being used, so slowing down the query.
Upvotes: 2
Reputation: 4061
try this
SELECT C.CustomerID, C.CompanyName FROM Customers C
WHERE
not exists(select 1 FROM Orders O where O.CustomerID = C.CustomerID and YEAR(O.OrderDate) = 1996)
ORDER BY C.CustomerID
Upvotes: 0