0

我有三个表:客户、订单和退款。一些客户(不是全部)下订单,一些订单(不是全部)有退款。

当我像这样加入三个表时(细节不是那么重要):

SELECT ...
FROM customers LEFT JOIN orders
ON customers.customer_id=orders.customer_id    
LEFT JOIN refunds
ON orders.order_id=refunds.order_id;
//WHERE order_id IS NOT NULL;// uncomment to filter out customers that have no orders

我得到一个大表,其中列出了所有客户(即使是那些没有下任何订单并且他们在 'order_id' 列中有 NULL 的客户),以及他们的所有订单和订单的退款(即使不是所有订单都有退款) ):

NAME     ORDER_ID    ORDER AMOUNT   REFUND
------------------------------------------------------------
Natalie   2         12.50           NULL
Natalie   3         18.00           18.00
Brenda    4         20.00           NULL
Adam      NULL      NULL            NULL    

由于我只想查看已下订单的客户,即在本例中我想从表中过滤 Adam,因此我从上面的 SQL 查询中取消注释“WHERE”行。这会产生所需的结果。我的问题是:在哪个表上执行 WHERE - 在原始“订单”表(没有为 NULL 的 order_id)或作为 JOIN 结果的表上?显然是后者,但只是想确定一下,因为从 SQL 语法上看不是很明显,这是非常重要的一点。

谢谢

4

3 回答 3

0

In this case, you're making SQL work harder than it has to. It is operating on the results (likely a MERGE event, or something along those lines).

There's a chance SQL is realizing what you're doing and optimizing the plan and changing to an INNER JOIN for you. But I can't be certain (and neither can SQL -- it can change how it optimizes over time).

In the case where you only want where an order is there, use an INNER JOIN instead. SQL will be much more efficient at this.

SELECT ...
FROM customers
INNER JOIN orders
ON customers.customer_id=orders.customer_id    
LEFT JOIN refunds
ON orders.order_id=refunds.order_id;
于 2013-09-19T12:55:45.020 回答
0

您可以将 LEFT JOIN 更改为 INNER JOIN 以消除没有任何订单的客户

SELECT ...
FROM customers INNER JOIN orders
ON customers.customer_id=orders.customer_id    
LEFT JOIN refunds
ON orders.order_id=refunds.order_id;
于 2013-09-19T12:58:16.517 回答
0

这是因为您正在使用LEFT JOIN,它将返回左侧表格中的所有行,在您的情况下,这是Customer表格,并返回NULL右侧表格中没有出现相应值的位置。

只需使用内部连接重写它,因此只会返回找到匹配数据的行。

SELECT ...
FROM customers 
INNER JOIN orders
    ON customers.customer_id=orders.customer_id    
INNER JOIN refunds
    ON orders.order_id=refunds.order_id;
于 2013-09-19T12:58:46.963 回答