Sql 在哪里使用临时表

Sql 在哪里使用临时表,sql,join,where,Sql,Join,Where,我有三张桌子:顾客、订单和退款。一些客户(并非所有客户)下了订单,一些订单(并非所有客户)获得了退款 当我像这样连接三个表时(细节没有那么重要): 我得到了一个大表,其中列出了所有客户(即使是那些没有下任何订单且在“订单id”列中为空的客户),以及他们的所有订单和订单退款(即使不是所有订单都有退款): 由于我只想看到已下订单的客户,即在本例中,我想从表中筛选Adam,因此我取消了上面SQL查询中“WHERE”行的注释。 这将产生预期的结果。 我的问题是: 在哪一个表上执行?在原始“orders”

我有三张桌子:顾客、订单和退款。一些客户(并非所有客户)下了订单,一些订单(并非所有客户)获得了退款

当我像这样连接三个表时(细节没有那么重要):

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

由于我只想看到已下订单的客户,即在本例中,我想从表中筛选Adam,因此我取消了上面SQL查询中“WHERE”行的注释。 这将产生预期的结果。 我的问题是: 在哪一个表上执行?在原始“orders”表(没有为NULL的order_id)上,还是在作为联接结果的表上? 显然是后者,但我只是想确定一下,因为从SQL语法来看这不是很明显,这是非常重要的一点


谢谢

在这种情况下,您让SQL工作起来比它必须的更努力。它正在对结果进行操作(可能是一个合并事件,或者类似的事件)

SQL有可能意识到您正在做什么,优化计划,并为您更改为
内部连接。但我不能确定(SQL也不能确定——它可以随着时间的推移改变优化的方式)

如果您只想要订单所在的位置,请使用
内部联接。SQL在这方面将更加高效

SELECT ...
FROM customers
INNER JOIN orders
ON customers.customer_id=orders.customer_id    
LEFT JOIN refunds
ON orders.order_id=refunds.order_id;

您可以将左连接更改为内部连接,以消除没有任何订单的客户

SELECT ...
FROM customers INNER JOIN orders
ON customers.customer_id=orders.customer_id    
LEFT JOIN refunds
ON orders.order_id=refunds.order_id;

这是因为您使用的是
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;

为什么不浏览一下执行计划,看看它在哪里执行?虽然我同意你的看法,但这种情况往往发生在最后一桌。你说得绝对正确,我确实试过这样做。但我运行这段代码(实际上是从一本书中)也是出于教育目的。即便如此,我想我还是用“这取决于”来回答这个问题。SQL是聪明的。它通常可以解决基于优化的问题。只有运行并分析计划,您才能确定。即使这样,也只能给你一个当前的优化过程。如果SQL改变了它的统计数据,并且认为用另一种方式进行会产生更好的结果,那么它会在以后重新优化查询。你最好尽可能明确你的意图来“保证”一个计划。
SELECT ...
FROM customers INNER JOIN orders
ON customers.customer_id=orders.customer_id    
LEFT JOIN refunds
ON orders.order_id=refunds.order_id;
SELECT ...
FROM customers 
INNER JOIN orders
    ON customers.customer_id=orders.customer_id    
INNER JOIN refunds
    ON orders.order_id=refunds.order_id;