首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Oracle中执行分层查询中的WHERE-子句

如何在Oracle中执行分层查询中的WHERE-子句
EN

Stack Overflow用户
提问于 2012-07-16 04:41:42
回答 2查看 7.4K关注 0票数 5

在Oracle层次查询中,WHERE子句应该在oracle文档中的Connect-By操作符之后进行计算。

但也有复杂的情况:如果WHERE子句包含联接样式的限定,正如甲骨文所说的那样,联接样式的限定应该在Connect-By运算符之前进行评估,而另一个只引用一个关系的连接样式则应该在Connect-By运算符之后进行评估。

因此,问题是:如何将WHERE-子句中的资格划分为两个部分,一个在Connect-By运算符之前进行评估,另一个在Connect-By运算符之后进行评估。

代码语言:javascript
复制
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子句形成?

谢谢。

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2012-07-16 08:45:44

不应使用隐式联接,而应使用显式JOINs。

一旦这样做,您就可以区分“真实”where条件和联接条件。

我不清楚(这是使用隐式联接语法的结果),您到底想要使用什么作为连接条件,使用什么作为where条件。

将查询重写为如下内容:

代码语言:javascript
复制
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,连接不会产生任何结果。

票数 1
EN

Stack Overflow用户

发布于 2012-07-17 06:56:09

如果需要显式拆分它,可以使用括号和内联视图进行拆分。

代码语言:javascript
复制
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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11498199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档