简体   繁体   English

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

[英]SQL - INNER JOIN with AND vs using sub-query

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 " . 我练的问题 “SQL实践问题:57初级,中级和高级的挑战,为您使用解决‘学边做’的方式”。 Question 31 is - 问题31是-

Customers with no orders for EmployeeID 4 没有订购EmployeeID 4的客户

One employee (Margaret Peacock, EmployeeID 4) has placed the most orders. 一位员工(玛格丽特·孔雀,员工ID 4)下了最多的订单。 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. 我所做的解决方案创建一个临时表“ cte”,并将其与现有表联接。 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 ? 我的问题-什么时候可以在JOIN使用ORAND子句? What are the advantages? 有什么优势? Is it the fact that a JOIN is executed before the where clause? JOIN是在where子句之前执行的事实吗?

Thanks, 谢谢,

Asaf 阿萨夫

A JOIN condition can contain any boolean comparison, even subqueries using EXISTS and correlated subqueries. JOIN条件可以包含任何布尔比较,甚至包括使用EXISTS和相关子查询的子查询。 There is no limitation on what can be expressed. 对可以表达的内容没有限制。

Just a note, however. 不过,请注意。 = and AND are good for performance. =AND对性能有好处。 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. 就是说,获得所有与员工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. 对我来说, JOIN很多比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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM