在应用任何连接之前,在行上应用WHERE
子句是否公平,而在所有连接和所有聚合之后,将在最终结果集上应用HAVING
子句功能已被应用?
答案 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子句中的过滤谓词在加入连接操作之前执行。至少“逻辑上”。但是,我可以想象一些涉及对物化视图进行查询重写的情况,例如带有索引的预连接表,当它在“引擎盖下”工作时有点不同。不过,结果是一样的。