不同之处在于条件是逻辑评估的地方,反过来又会影响结果集。
在你的例子(重新格式化),您有:
实施例1
SELECT COUNT(*)
FROM A LEFT JOIN B ON a.id = b.id
WHERE a.status = 2 AND b.id is NULL
实施例2
SELECT COUNT(*)
FROM A LEFT JOIN B ON a.id = b.id AND a.status = 2
WHERE b.id is NULL
在第一种情况中,LEFT JOIN被施加并生成结果集;然后使用WHERE子句中的两个条件对其进行过滤。
在第二种情况下,LEFT JOIN由a.status
上的筛选条件构成,并且在某些情况下可能会从LEFT JOIN更改结果集。然后使用主WHERE子句过滤此结果集。
实施例2基本上等同于:
实施例2A
SELECT COUNT(*)
FROM (SELECT * FROM A WHERE a.status = 2) AS A
LEFT JOIN B ON a.id = b.id
WHERE b.id is NULL
对于某些查询(但可能不是这样的一个),差异可以无关紧要。
让我们尝试创建一些简单的示例数据:
Table A Table B
id status id
4 2 1
5 3
实施例1将具有中间结果集:
a.id a.status b.id
4 2 null
5 3 null
和WHERE子句消除的第二行。
实施例2将具有中间结果集:
a.id a.status b.id
4 2 null
在本例中,最终结果是一样的,并且我还没有能够拿出数据不结束的相同。
如果四处移动的查询条件位于外连接表上并且比简单的相等性更复杂,则可以看到效果。
我明白了,所以查询1更好。我正确地假设,如果它是“B.status = 2”,那么它将在你的query2的例子1中存在()子句,所以(SELECT * from b WHERE a.id a = b.id AND b。状态= 2)? – edelwater 2012-02-27 00:08:32
查询1和2不同,它们返回不同的结果。查询1不是更好,但更常见。在实际情况下,我从来没有遇到过Query2类型。 – 2012-02-27 00:10:19
是的,对于第二个问题,一个'b.status = 2'条件会显着改变事物。这是非常普遍的情况(并且让它与左连接一起工作,您将该条件放在“ON”部分中)。 – 2012-02-27 00:12:05