是否在JOIN之前应用了WHERE子句

时间:2014-06-25 20:13:50

标签: oracle join where having

在应用任何连接之前,在行上应用WHERE子句是否公平,而在所有连接和所有聚合之后,将在最终结果集上应用HAVING子句功能已被应用?

2 个答案:

答案 0 :(得分:2)

  

在应用任何连接之前,在行数据上应用WHERE子句是否公平

不,优化器可能会更改已连接表的顺序。因此,连接表可能在技术上先于您在FROM中指定的表格。从技术上讲,WHERE的条件可能会成为JOIN条件的一部分。

  在所有连接和所有聚合函数都已应用之后,

HAVING子句将应用于最终结果集

那是对的

答案 1 :(得分:0)

WHERE vs HAVING仅对包含GROUP BY子句的SQL语句有意义。首先应用WHERE子句中的过滤谓词,然后应用聚合,然后在HAVING子句中过滤谓词。

示例:

create table t(
   a varchar2(10) not null
  ,b varchar2(10) not null
  ,n number       not null
  ,primary key(a,b) 
);

insert into t values('A', '1', 10);
insert into t values('A', '2', 20);

insert into t values('B', '1', -10);
insert into t values('B', '2', 10);

insert into t values('C', '1', 0);
insert into t values('C', '2', 10);
insert into t values('C', '3', 20);

在以下查询中,在聚合之前删除{C,1}。查看计数(*)。

select a, sum(n), count(*)
  from t
 where n <> 0
 group by a;

A  SUM(N) COUNT(*)
== ====== =====
A  30     2
B  0      2
C  30     2

在此查询中,{B,1}和{B,2}都被删除,因为它们的总和为0.但请注意,包括{C,1}。

select a, sum(n), count(*)
  from t
 group by a
 having sum(n) <> 0; 

A  SUM(N) COUNT(*)
== ====== =====
A  30     2
C  30     3

最后一点说明: WHERE子句中的过滤谓词在加入连接操作之前执行。至少“逻辑上”。但是,我可以想象一些涉及对物化视图进行查询重写的情况,例如带有索引的预连接表,当它在“引擎盖下”工作时有点不同。不过,结果是一样的。