在WHERE子句和JOIN条件中使用过滤条件有什么区别

时间:2015-05-31 16:13:19

标签: sql

假设我有任何连接类型的跟随加入查询(INNER / LEFT / RIGHT / FULL)

SELECT E.id, D.name, E.sal from EMP E
INNER/LEFT/RIGHT/FULL JOIN DEP D
ON E.id = D.id
AND E.sal > 100

另外,我有与WHERE条件类似的查询

SELECT E.id, D.name, E.sal from EMP E
INNER/LEFT/RIGHT/FULL JOIN DEP D
ON E.id = D.id
WHERE E.sal > 100

以上查询的唯一区别是使用E.sal> JOIN和WHERE条件中的100。

在哪种情况下,上述查询的结果会有所不同?或两者始终相同?

1 个答案:

答案 0 :(得分:6)

使用INNER JOIN,无论是在性能还是结果集的定义方面都没有区别。与OUTER JOIN s有所不同。

WHERE子句在评估FROM后过滤FROM 的结果。因此,请考虑以下两个问题:

SELECT E.id, D.name, E.sal
from EMP E LEFT JOIN
     DEP D
     ON E.id = D.id
WHERE E.sal > 100;

SELECT E.id, D.name, E.sal
from EMP E LEFT JOIN
     DEP D
     ON E.id = D.id AND E.sal > 100;

第一个过滤EMP表以获取适当的ID。第二个过滤EMP表。为什么不?好吧,LEFT JOIN的定义表示要占用第一个表中的所有行,无论ON是否在第二个表中找到匹配的记录。所以,没有过滤。

现在,请考虑以下版本:

SELECT E.id, D.name, E.sal
from EMP E RIGHT JOIN
     DEP D
     ON E.id = D.id
WHERE E.sal > 100;

SELECT E.id, D.name, E.sal
from EMP E RIGHT JOIN
     DEP D
     ON E.id = D.id AND E.sal > 100;

第一个将RIGHT JOIN变为INNER JOIN。为什么?因为对于不匹配的行,E.salNULL并且WHERE失败。第二个版本保留所有部门,甚至那些没有员工匹配条件的部门。注意:在遵循逻辑方面,我(和其他人)更喜欢左外连接到右外连接。 left 外连接的逻辑很简单:将所有行保留在第一个表中。

FULL OUTER JOIN结合了这两种情况。