2011-12-09 35 views
6

在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

他们是,应该是不同的。

考虑一下你有一个与商家和agend id匹配的b,并且b.default不为null的情况。

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

在第二种情况下,您会找到a并找到匹配的b。但是因为b失败了WHERE子句,记录被排除在输出之外。

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

1

第一个将向您显示只匹配来自B的记录,对于default,其值也为NULL

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

但是,您还应该注意,当您在WHERE子句中JOIN ed表上过滤时,您将强制执行INNER JOIN,因此实际上在这里有两个问题。

0

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

WHERE子句过滤结果集,而ON子句停止行加入首位。结果集可能很大,在处理大型结果集方面做了很多工作。如果你想加入到其他表中,它会产生很大的差异,因为停止加入前面的行可以切断大量的行。

大多数现代解析器都会优化查询,所以性能效果应该是相同的。

最后,因为WHERE子句过滤,左连接将保留至少有一行具有ON子句中的条件,但是在WHERE子句中将条件抛出。

+0

就是这样。我在我的实际查询中还有其他连接,并且存在很大的显着差异。但第一种情况比第二种情况产生更多的情况。直觉上,就像你说的那样,它不应该是相反的吗? – flipflop99