我正在练习书“SQL 练习问题:57 个初级、中级和高级挑战,供您使用“边做边学”方法解决”。
没有 EmployeeID 4 订单的客户
一名员工(Margaret Peacock,员工 ID 4)下的订单最多。然而,有些顾客从未向她下过订单。只显示那些从未向她下过订单的顾客。
我的解决方案创建一个临时 CTE 表并将其与现有表连接。
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
我找到了以下更好的解决方案。
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;
我什么时候可以在
OR
中使用 AND
、JOIN
子句?
有什么优势?
是否JOIN是在where子句之前执行的?
JOIN
条件可以包含任何布尔比较,甚至使用EXISTS
的子查询和相关子查询。 可以表达的内容没有限制。
不过,请注意。
=
和 AND
有利于性能。 不平等往往会成为绩效杀手。
对于你的具体问题,我认为以下是对该问题更直接的解释:
SELECT c.CustomerID
FROM Customers c
WHERE NOT EXISTS (SELECT 1
FROM Orders o
WHERE o.CustomerID = c.CustomerID AND
o.EmployeeID = 4
);
即获取员工4没有订单的所有客户。
一般来说,我建议您始终选择最可读的查询版本,除非您可以实际测量与实际数据的性能差异。在这种情况下,基于成本的优化器应该选择一种执行查询的好方法来返回您想要的结果。
对我来说,
JOIN
比 CTE 更具可读性。
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