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

log*_*gan 3 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
Run Code Online (Sandbox Code Playgroud)

另外,我有与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
Run Code Online (Sandbox Code Playgroud)

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

在哪种情况下,上述查询会有不同的结果 或者两者都一样吗?

Gor*_*off 6

对于a INNER JOIN,在性能或结果集的定义方面没有区别.与OUTER JOINs 有所不同.

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;
Run Code Online (Sandbox Code Playgroud)

第一个过滤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;
Run Code Online (Sandbox Code Playgroud)

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

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