I'm practicing questions for the book "SQL Practice Problems: 57 beginning, intermediate, and advanced challenges for you to solve using a “learn-by-doing” approach " . Question 31 is -
Customers with no orders for EmployeeID 4
One employee (Margaret Peacock, EmployeeID 4) has placed the most orders. However, there are some customers who've never placed an order with her. Show only those customers who have never placed an order with her.
The solution I did creates a temporary table "cte" and joints it with an existing table. Not pretty or readable actually -
with cte as
(Select Customers.CustomerID
from customers
where CustomerID not in
(select Orders.CustomerID from orders where orders.EmployeeID = '4'))
select *
from cte left join
(select CustomerID from Orders where Orders.EmployeeID = '4') O
on cte.CustomerID = O.CustomerID
I found the following solution online -
SELECT c.CustomerID, o.CustomerID
FROM Customers AS c
LEFT JOIN Orders AS o ON o.CustomerID = c.CustomerID AND o.EmployeeID = 4
WHERE o.CustomerID IS NULL;
Which is nicer.
My question - when can I use OR
, AND
clauses in a JOIN
? What are the advantages? Is it the fact that a JOIN is executed before the where clause?
Thanks,
Asaf
A JOIN
condition can contain any boolean comparison, even subqueries using EXISTS
and correlated subqueries. There is no limitation on what can be expressed.
Just a note, however. =
and AND
are good for performance. Inequalities tend to be performance killers.
As for your particular problem, I think the following is a more direct interpretation of the question:
SELECT c.CustomerID
FROM Customers c
WHERE NOT EXISTS (SELECT 1
FROM Orders o
WHERE o.CustomerID = c.CustomerID AND
o.EmployeeID = 4
);
That is, get all customers for whom no order exists with employee 4.
Generally I'd recommend that you always choose the most readable version of the query unless you can actually measure a performance difference with realistic data. The cost based optimiser should pick a good way of executing the query to return the results you want in this case.
For me the JOIN
is a lot more readable than the CTE.
Here's is another Solution
SELECT * FROM(
(SELECT Customers.CustomerID AS Customers_ID
FROM Customers) AS P
LEFT JOIN
(Select Orders.CustomerID from Orders
where Orders.EmployeeID=4) as R
on R.CustomerID = P.Customers_ID
)
WHERE R.CustomerID IS NULL
ORDER BY R.CustomerID DESC
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.