如何在Oracle中的分层查询中执行WHERE-CLAUSE
在Oracle分层查询中,应在Oracle文档中的Connect-By操作符说明之后评估WHERE-CLAUSE。如何在Oracle中的分层查询中执行WHERE-CLAUSE
但也有复杂的情况:如果WHERE-CLAUSE包含JOIN样式限定条件,如oracle所述,Join-Style限定条件应在Connect-By操作符之前进行评估,而另一个无参考样式仅限于Connect-By操作符后将评估一个关系。
所以问题是:如何将WHERE-CLAUSE中的资格区分为两部分,一部分在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 OR “B1”= 1)AND “F1” IS NOT NULL) - >评估后连接-由
的其他:过滤器(“F1”=“B2”或“F2”=“B1”+1)和访问(“F1”=“B1”) - >在连接前评估为JOIN-ON
那么,谁可以解释如何区分WHERE子句中的条件以及如何在连接之前或之后应用WHERE子句中的两个部分?
谢谢。
谢谢。
您不应该使用隐式联接,而应该使用显式的JOIN
。
一旦你这样做,你可以区分条件与连接条件的“真实”。
我不清楚(这是使用隐式连接语法的结果)您想要用作连接条件的什么以及作为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是空反正不会产生任何结果。
但我想知道在分层查询中拆分WHERE子句的规则。它是否是oracle的版权? – user1527818 2012-07-16 08:49:47
@ user1527818:对不起,你失去了我。 – 2012-07-16 09:02:44
如果您需要明确拆分它,可以使用括号和内嵌视图来完成。
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;
使用JOIN语法加入和条件***的WHERE子句是***您的问题的答案。这正是这些结构的用途。它使你的发言意图更清晰。 – 2012-07-17 07:27:47