Oracle 階層クエリでは、Oracle ドキュメントの Connect-By 演算子の後に WHERE-CLAUSE を評価する必要があります。
しかし、複雑な状況があります。オラクルが言うように、WHERE-CLAUSE に JOIN スタイルの修飾が含まれている場合、Connect-By 演算子の前に Join-Style 修飾を評価する必要があり、1 つの関係のみを参照する他の非結合スタイルが評価されます。 Connect-By 演算子の後に評価されます。
問題は、WHERE-CLAUSE の条件を 2 つの部分に区別する方法です。1 つは Connect-By 演算子の前に評価され、もう 1 つは 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 and (b2 = 1 or f1=b2 and b1=1 or f2=b1+1) and f1 is not null の条件は、次の 2 つの部分になります。
one: filter(("B2"=1 OR "B1"=1) AND "F1" IS NOT NULL) --> 接続後に評価
その他: filter("F1"="B2" OR "F2"="B1"+1) and access("F1"="B1") --> connect-by の前に JOIN-ON として評価
では、WHERE 句の条件を区別する方法と、connect-by の前後に適用される WHERE 句から 2 つの部分を形成する方法を誰が説明できますか?
ありがとう。
ありがとう。