考虑这两个类似的SQL
(ON条款中的条件)
select t1.field1, t2.field1
from
table1 t1 inner join table2 t2 on t1.id = t2.id and t1.boolfield = 1
(WHERE子句中的条件)
select t1.field1, t2.field1
from
table1 t1 inner join table2 t2 on t1.id = t2.id
where t1.boolfield = 1
我已经对此进行了一些测试,我可以看到在外连接的两个不同位置放置条件之间的区别。 但是在内连接的情况下,结果集可能会有所不同吗?
答案 0 :(得分:5)
对于INNER JOIN,没有任何有效的区别,尽管我认为第二种选择更清晰。
对于LEFT JOIN,存在巨大差异。 ON子句指定从表中选择哪些记录进行比较,WHERE子句过滤结果。
示例1:返回tbl 1中的所有行,并将它们与来自tbl2的具有boolfield = 1的适当行匹配
Select *
From tbl1
LEFT JOIN tbl2 on tbl1.id=tbl2.id and tbl2.boolfield=1
示例2:将仅包含来自tbl1的行,这些行在tbl2中具有与boolfield = 1匹配的行。它连接表,然后过滤掉不符合条件的行。
Select *
From tbl1
LEFT JOIN tbl2 on tbl1.id=tbl2.id
WHERE tbl2.boolfield=1
答案 1 :(得分:2)
在您的特定情况下,t1.boolfield指定了另一个选择条件,而不是匹配两个表之间记录的条件,因此第二个示例更正确。
如果您正在谈论将匹配记录的条件放入ON子句与WHERE子句中的情况,see this question。
答案 2 :(得分:1)
两个版本都返回相同的数据。
虽然对于内部联接也是如此,但对于外部联接却不是这样。
在风格上,还有第三种可能性。除了你的两个,还有:
select t1.field1, t2.field1
from (select t1.*
from table1 t1
where t1.boolfield = 1
) t1 inner join
table2 t2
on t1.id = t2.id
哪个更好取决于您要突出显示的内容,因此您(或其他人)可以在以后理解和修改查询。我经常更喜欢第三个版本,因为它强调查询只使用表中的某些行 - 布尔条件非常接近指定表的位置。
在另外两种情况下,如果你有一个很长的查询,那么找出“t1”的真正含义可能会有问题。我想这就是为什么有些人喜欢把条件放在ON子句中。其他人更喜欢WHERE子句。