位置条件的排列顺序是否重要?

6
以下两个查询语句给出了不同的结果:
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'

And

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个回答

3

它们是不同的,而且应该是不同的。

考虑这样一种情况:您有一个具有匹配商家和代理ID的b的a,并且b.default不为null。

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

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

如果您正在进行完全连接,在ON和WHERE中放置条件不会更改输出。但是在左联接或右联接上,它确实会按照我试图描述的方式更改输出。


1

第一个将仅显示具有 null 值的默认值的记录。

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

但是,您也应该知道,在 WHERE 子句中筛选 JOIN 表时,您正在强制使用 INNER JOIN,因此实际上存在两个问题。


0

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

WHERE子句过滤结果集,而ON子句阻止行在第一次连接时加入。结果集可能很大,在处理大型结果集方面需要大量工作。如果您要连接其他表,它将产生很大的差异,因为较早地停止行连接可以切断后面的大量行。

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

最后,由于WHERE子句进行过滤,左连接将保留至少一行具有ON子句中的条件,但使用WHERE子句中的条件将其排除。


那就是问题所在。我的实际查询中确实有其他的连接,而且有明显的差异。但第一种情况比第二种情况产生更多的结果。直觉上,就像你说的那样,难道不应该是相反的吗? - flipflop99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接