以下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
我假设条件对两个查询执行相同的操作,仅在不同时间执行。我错过了什么吗?
答案 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子句中的条件一起抛出。