在Oracle层次查询中,WHERE子句应该在oracle文档中的Connect-By操作符之后进行计算。
但也有复杂的情况:如果WHERE子句包含联接样式的限定,正如甲骨文所说的那样,联接样式的限定应该在Connect-By运算符之前进行评估,而另一个只引用一个关系的连接样式则应该在Connect-By运算符之后进行评估。
因此,问题是:如何将WHERE-子句中的资格划分为两个部分,一个在Connect-By运算符之前进行评估,另一个在Connect-By运算符之后进行评估。
example:
SQL> desc bar
Name Null? Type
----------------------------------------- -------- -----------------
B1 NUMBER(38)
B2 NUMBER(38)
SQL> desc foo;
Name Null? Type
----------------------------------------- -------- -----------------
F1 NUMBER(38)
F2 NUMBER(38)
SQL> set pagesize 3000
SQL> set linesize 3000
SQL> explain plan for select * from foo, bar where
2 **f1=b1 and (b2 = 1 or f1=b2 and b1=1 or f2=b1+1) and f1 is not null**
3 connect by level < 10;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Plan hash value: 2657287368
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 52 | 5 (20)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | CONNECT BY WITHOUT FILTERING| | | | | |
|* 3 | HASH JOIN | | 1 | 52 | 5 (20)| 00:00:01 |
| 4 | TABLE ACCESS FULL | FOO | 1 | 26 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | BAR | 1 | 26 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - **filter(("B2"=1 OR "B1"=1) AND "F1" IS NOT NULL)**
2 - filter(LEVEL<10)
3 - **access("F1"="B1")**
**filter("F1"="B2" OR "F2"="B1"+1)**
Note
-----
- dynamic sampling used for this statement
24 rows selected.因此,正如上面的计划所示,WHERE、f1=b1和(b2 =1或f1=b2和b1=1或f2=b1+1)和f1中的条件不为空,已成为两个部分:
第一种:过滤器(“B2”=1或"B1"=1)和"F1“不是空) -->连接后的计算
另一个是:过滤器(“F1”=“B2”或"F2"="B1"+1)和access("F1"="B1")
因此,谁能解释如何区分WHERE子句中的条件,以及如何将这两个部分与在connect?之前或之后应用的WHERE子句形成?
谢谢。
谢谢。
发布于 2012-07-16 08:45:44
不应使用隐式联接,而应使用显式JOINs。
一旦这样做,您就可以区分“真实”where条件和联接条件。
我不清楚(这是使用隐式联接语法的结果),您到底想要使用什么作为连接条件,使用什么作为where条件。
将查询重写为如下内容:
from foo
join bar on foo.f1 = bar.b1
where bar.b2 = 1 or ....
and f1 is not null
connect by level < 10;条件f1 is not null似乎没有必要(即使在初始查询中也是如此),因为如果f1为null,连接不会产生任何结果。
发布于 2012-07-17 06:56:09
如果需要显式拆分它,可以使用括号和内联视图进行拆分。
select *
from (select *
from foo, bar
where f1=b1 and (b2 = 1 or f1=b2 and b1=1 or f2=b1+1) and f1 is not null)
connect by level < 10;https://stackoverflow.com/questions/11498199
复制相似问题