将一个条件放在内连接的ON子句和主查询的where子句之间是否存在逻辑差异?

时间:2012-07-19 18:45:13

标签: sql join

考虑这两个类似的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

我已经对此进行了一些测试,我可以看到在外连接的两个不同位置放置条件之间的区别。 但是在内连接的情况下,结果集可能会有所不同吗?

3 个答案:

答案 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子句。