SQL-使用AND与使用子查询进行INNER JOIN

时间:2019-05-15 10:57:47

标签: sql sql-server join common-table-expression

我正在练习book的问题,“ SQL练习问题:使用“边做边学”的方法可以解决的57个开始,中级和高级的挑战” 。问题31是-

未订购EmployeeID 4的客户

一名员工(玛格丽特·孔雀,员工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中使用ANDJOIN子句?有什么优势?是在where子句之前执行JOIN的事实吗?

谢谢

Asaf

3 个答案:

答案 0 :(得分:1)

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没有订单的客户。

答案 1 :(得分:0)

通常,我建议您始终选择查询最易读的版本,除非您可以实际测量实际数据的性能差异。在这种情况下,基于成本的优化程序应该选择一种执行查询以返回所需结果的好方法。

对我来说,JOIN比CTE更具可读性。

答案 2 :(得分:0)

这是另一个解决方案

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