条件的放置是否重要?

时间:2011-12-09 21:04:25

标签: sql postgresql

以下2个查询给出了不同的结果:

SELECT A.source_code, B.quantity
FROM Table_A AS A
LEFT JOIN Table_B AS B ON B.merchant_id = A.merchant_id
   AND B.agent_id = A.agent_id
   AND B.default IS NULL
WHERE A.month='2011-10-01'
   AND B.type='600'

并且

SELECT A.source_code, B.quantity
FROM Table_A AS A
LEFT JOIN Table_B AS B ON B.merchant_id = A.merchant_id
   AND B.agent_id = A.agent_id
WHERE A.month='2011-10-01'
   AND B.type='600'
   AND B.default IS NULL

我假设条件对两个查询执行相同的操作,仅在不同时间执行。我错过了什么吗?

3 个答案:

答案 0 :(得分:3)

它们应该是不同的。

考虑这样一种情况:你有一个b与商家和年龄id匹配的b,而b.default不是null。

在第一种情况下,你会找到a,然后找不到满足条件的b,因为没有b匹配id的AND并且默认为null。但是因为它是左连接,你仍然可以在输出中获得带有“a”数据的记录。

在第二种情况下,您将找到a并找到匹配的b。但是因为b未通过WHERE子句,所以记录将从输出中排除。

如果您正在进行完全连接,则将条件置于ON与WHERE之间将不会更改输出。但是在左边或右边连接处,它会按照我上面描述的方式更改输出。

答案 1 :(得分:1)

第一个将仅显示来自B的匹配记录,NULL的值为default

第二个变体将显示B的所有记录,因为在OUTER JOIN执行后应用了过滤器。由于不匹配的记录显示NULL值,因此匹配所有记录。

但是,您还应该注意,当您在JOIN子句中的WHERE ed表上过滤时,您正在强制使用INNER JOIN,因此您实际上有两个问题在这里工作

答案 2 :(得分:0)

不完全是,但在这种情况下是。

WHERE子句过滤结果集,而ON子句在第一个位置停止加入行。结果集可能很大,在处理大型结果集方面做了大量工作。如果你要加入其他表,那将会产生很大的不同,因为停止加入之前的行可以在以后切断大量的行。

大多数现代解析器无论如何都会优化查询,因此性能影响应该是相同的。

最后,因为WHERE子句过滤了,所以左连接保持至少一行,其中包含ON子句中的条件,但是将其与WHERE子句中的条件一起抛出。