WHERE子句限制行左连接

时间:2017-07-20 09:41:42

标签: oracle join

我不明白为什么下面的这两个查询会获取不同的计数。下面的情况1获取更多行,而情况2获取更少的行。如果将where子句放在外面,则会获取更少的记录。

案例1

SELECT COUNT(1) 
FROM (
    SELECT * 
    FROM (SELECT * FROM TABLE1 WHERE COL1 = 123) A
          LEFT JOIN TABLE2 B ON B.COL2=A.COL4
          LEFT JOIN TABLE3 C ON C.COL3=B.COL2
      )

案例2

SELECT COUNT(1) 
FROM (
    SELECT * 
    FROM (SELECT *  FROM TABLE1 ) A
         LEFT JOIN TABLE2 B ON B.COL2=A.COL4
         LEFT JOIN TABLE3 C ON C.COL3=B.COL2
   ) 
WHERE COL1 = 123

1 个答案:

答案 0 :(得分:1)

理论解释:

考虑表A和B的左外连接。如果表B中的条件(过滤器)处于连接条件(ON子句)与WHERE子句中,则它具有不同的效果。 编辑:B处于ON状态的过滤器相当于将B替换为首先应用过滤器的子查询(类似于OP的示例)。

如果它在ON子句中,那么表B中的行将针对该条件进行过滤,然后执行左连接。然后,只要B中没有满足过滤器的行并且在连接条件下匹配A中的行,查询的结果将包括来自A的行(B侧为NULL)。

另一方面,如果B上的过滤器在执行后期出现,则在WHERE子句中,首先执行左连接。只有这样才应用WHERE子句。 WHERE子句很可能(取决于B上的条件)拒绝A中没有B中匹配行的所有行 - 因为对于这样的行,B中的所有值都是NULL。

在你的情况下,假设COL1仅存在于表B中,那么WHERE子句中的条件COL1 = 123将有效地使左连接产生与内连接相同的结果:来自A的任何没有的行B中的匹配将来自左连接,COL1为NULL,因此它们将使过滤条件失败。当您在ON子句中放置COL1 = 123时,该检查在“外连接”操作之前完成。