Identify cycles recursive subquery factoring (RSF/CTE)
It is possible to detect cycles AFTER executing a recursive factoring subquery with the cycle_clause.
I need to detect already in the query, similar to the virtual CONNECT_BY_ISCYCLE in a hierarchical query.
Here is a test case of the use of factoring of the recursive subquery (RSF) to the algorithm of Dijkstra shortest Implement path?.
DROP TABLE edges;
CREATE TABLE edges (char (1) src, dst char (1), distance, NUMBER (3, 0));
DROP TABLE nodes.
CREATE TABLE nodes (nodes CHAR (1));
-INSERTION in the edges
-normal direction
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('A', '' B, 2');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('A', 'C', '4');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('A' 'd', '3' ");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES (' B', 'E', 7' ");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ("C", "E", "3");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES (', 'E', '4');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES (' B', 'F', 4' ");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('C', 'F', "2");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES (', 'F', '1');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES (' B', 'G', 6' ");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('C', 'G', "4");
INSERT INTO edges (SRC, DST, DISTANCE) VALUES (', 'G', '5');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('E', 'H', '1');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('F', 'H', '6');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('G', 'H', '3');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('E', 'I', '4');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('F', 'I', '3');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('G', 'I', '3');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('H', 'J', '3');
INSERT INTO edges (SRC, DST, DISTANCE) VALUES ('I', 'J', '4');
-inversion
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('A', '' B, 2');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('A', 'C', '4');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('A' 'd', '3' ");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES (' B', 'E', 7' ");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ("C", "E", "3");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES (', 'E', '4');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES (' B', 'F', 4' ");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('C', 'F', "2");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES (', 'F', '1');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES (' B', 'G', 6' ");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('C', 'G', "4");
INSERT INTO edges (DST, SRC, DISTANCE) VALUES (', 'G', '5');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('E', 'H', '1');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('F', 'H', '6');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('G', 'H', '3');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('E', 'I', '4');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('F', 'I', '3');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('G', 'I', '3');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('H', 'J', '3');
INSERT INTO edges (DST, SRC, DISTANCE) VALUES ('I', 'J', '4');
-SELECT the recursive subquery factoring (RSF) / Common Table Expressions (CTE)
-INCLUDE the starting point of Sub
WITH the railways (root, src, dst, path, distance, cost, lev, iscyc) AS
(SELECT 'A', NULL, 'A', 'A', 0, 0, 1, 0
OF the double
UNION ALL
SELECT p.root,
e.SRC,
e.DST,
p.Path | ',' || e.DST,
e.distance,
p.cost + e.distance,
p.Lev + 1,
-good idea?
p.iscyc
RAILWAYS p
JOIN the edges e WE (e.src = p.dst)
AND lev + 1 < = 3
)
Lev RESEARCH FIRST WIDTH, cost line_no SET
CYCLE of dst SET is_cycle to 1 by DEFAULT 0
SELECT *.
TRAIL pr
WHERE 1 = 1
- AND is_cycle = 0
- AND DST = 'J '.
ORDER BY lev;
DISTANCE FROM ROOT SRC DST LEV ISCY LINE_NO IS_CYCLE COST PATH
-------------------------------------------------------------------
A A A 0 0 1 0 1 0
A A D A,D 3 3 2 0 3 0
A A B A,B 2 2 2 0 2 0
A A C A,C 4 4 2 0 4 0
A C F A,C,F 2 6 3 0 9 0
A E C E A, C, 3 7 3 0 10 0
AN E D A, D, E 4 7 3 0 11 0
B G G, B, 6 8 3 0 12 0
A C AN A, C, 4 8 3 0 13 1
A D G, D, G 5 8 3 0 14 0
G C G, C, 4 8 3 0 15 0
B E A, B, E 7 9 3 0 16 0
A B F A,B,F 4 6 3 0 7 0
A B A A,B,A 2 4 3 0 6 1
A D F A,D,F 1 4 3 0 5 0
A D A A,D,A 3 6 3 0 8 1
There is a powerful way to fill the column ISCY, while the recursion like the IS_CYCLE column?
I tried the table nested in CTE before but had a few questions. The code below works in 11g but not 12 c:
create or replace type nt_char in the table to the varchar2 (20);
/
WITH the railways (root, src, dst, path, distance, cost, lev, iscyc) AS
(SELECT 'A', NULL, 'A', CAST (nt_char ('A') AS nt_char), 0, 0, 1, 0)
OF the double
UNION ALL
SELECT p.root,
e.SRC,
e.DST,
nt_char (e.dst) MULTISET UNION ALL p.Path,
e.distance,
p.cost + e.distance,
p.Lev + 1,
CASE WHEN e.dst MEMBER OF p.path, 1 ELSE 0 END AS iscyc
RAILWAYS p
JOIN the edges e WE (e.src = p.dst)
AND lev + 1<>
)
Lev RESEARCH FIRST WIDTH, cost line_no SET
CYCLE of dst SET is_cycle to 1 by DEFAULT 0
SELECT *.
TRAIL pr
WHERE 1 = 1
- AND is_cycle = 0
- AND DST = 'J '.
ORDER BY lev;
Tags: Database
Similar Questions
-
The recursive subquery factoring vs hierarchical query
Experts,
Here it is two queries, I'm executing using hierarchical of recursive subquery and new classical approach. Problem came out was different for the recursive subquery factoring, as this is not displayed parent-child approach, while forwards connect shows parent-child mode. Query 1, I use hierarchical as show good output parent-child, is approaching the 2 query displays all of the nodes of level 1 and then level 2 nodes. I want the query 2 output to be the same as query 1. change query 2 as required.
Note: the output of the two queries post as in sqlplus and toad. Please copy and use in your command prompt.
QUERY 1:
with the hand in the form (select 1 id, name 'John', null, mgrid Union double all the)
Select 2 id, the name of 'michael', null, mgrid Union double all the
Select 3 id, the name of "peter", null, mgrid Union double all the
Select 4 id, the name of "henry", 1 mgrid Union double all the
Select 5 id, "nickname", mgrid 2 Union double all the
Select 6 id, "pao" name, mgrid 3 of all the double union
Select 7 id, the name of 'kumar', mgrid 3 of all the double union
Select 8 id, the name 'parker', mgrid 3 of all the double union
Select 9 id, the name of "mike", 5 double mgrid),
Select lpad (' ', 2 *(level-1)). name, key start with mgrid level is null connect by prior id = mgrid.
OUTPUT:
LEVEL NAME
------------------------------ ----------
John 1
Henry 2
Michael 1
Nick 2
Mike 3
Stone 1
PAO 2
Kumar 2
Parker 2
9 selected lines.
QUERY 2:
with the hand in the form (select 1 id, name 'John', null, mgrid Union double all the)
Select 2 id, the name of 'michael', null, mgrid Union double all the
Select 3 id, the name of "peter", null, mgrid Union double all the
Select 4 id, the name of "henry", 1 mgrid Union double all the
Select 5 id, "nickname", mgrid 2 Union double all the
Select 6 id, "pao" name, mgrid 3 of all the double union
Select 7 id, the name of 'kumar', mgrid 3 of all the double union
Select 8 id, the name 'parker', mgrid 3 of all the double union
Select 9 id, the name of "mike", 5 double mgrid),
/ * Select lpad (' ', 2 *(level-1)). name, key start with mgrid level is null connect by prior id = mgrid. * /
secmain (id, name, mgrid, hierlevel) as (select id, name, mgrid, 1 hierlevel of the main where mgrid is null
Union of all the
Select m.id, $m.name, m.mgrid, sm.hierlevel + 1 in m main join secmain sm on(m.mgrid=sm.id))
cycle is_cycle set id 1 default 0
Select lpad (' ', 2 *(hierlevel-1)). name, secmain hierlevel.
OUTPUT:
NAME HIERLEVEL
------------------------------ ----------
John 1
Michael 1
Stone 1
Henry 2
Nick 2
Parker 2
Kumar 2
PAO 2
Mike 3
9 selected lines.For example
SQL> with main as(select 1 id,'john' name,null mgrid from dual union all 2 select 2 id,'michael' name,null mgrid from dual union all 3 select 3 id,'peter' name,null mgrid from dual union all 4 select 4 id,'henry' name,1 mgrid from dual union all 5 select 5 id,'nick' name,2 mgrid from dual union all 6 select 6 id,'pao' name,3 mgrid from dual union all 7 select 7 id,'kumar' name,3 mgrid from dual union all 8 select 8 id,'parker' name,3 mgrid from dual union all 9 select 9 id,'mike' name,5 mgrid from dual), 10 secmain (id,name,mgrid,hierlevel) as 11 (select id,name,mgrid,1 hierlevel from main 12 where mgrid is null 13 union all 14 select m.id,m.name,m.mgrid,sm.hierlevel+1 from main m join secmain sm on(m.mgrid=sm.id)) 15 search depth first by name set seq 16 cycle id set is_cycle to 1 default 0 17 select lpad(' ',2*(hierlevel-1))||name name,hierlevel from secmain order by seq; NAME HIERLEVEL ---------- ---------- john 1 henry 2 michael 1 nick 2 mike 3 peter 1 kumar 2 pao 2 parker 2 9 rows selected. SQL>
Published by: Dom Brooks on November 23, 2011 13:52
Edited for the scope of the search and detection of cycle -
Recursive subquery factoring: calculate aggregates
Table T represents a tree. Each record is a node, and each node has only one parent. This query calculates the SUM() of each branch for each node.
WITH T AS (SELECT 1 ID, NULL parent_id, NULL VALUE FROM dual UNION ALL SELECT 10 ID, 1 parent_id, 1000 VALUE FROM dual UNION ALL SELECT 20 ID, 1 parent_id, 2000 VALUE FROM dual UNION ALL SELECT 30 ID, 10 parent_id, 3000 VALUE FROM dual UNION ALL SELECT 40 ID, 10 parent_id, 4000 VALUE FROM dual UNION ALL SELECT 50 ID, 20 parent_id, 5000 VALUE FROM dual UNION ALL SELECT 60 ID, 1 parent_id, 6000 VALUE FROM dual UNION ALL SELECT 70 ID, 60 parent_id, 7000 VALUE FROM dual UNION ALL SELECT 80 ID, 70 parent_id, 8000 VALUE FROM dual ) SELECT CAST(LPAD(' ', (LEVEL-1)*4) || ID AS VARCHAR2(20)) id ,VALUE self_value , (SELECT SUM (VALUE) FROM T t2 CONNECT BY PRIOR t2.ID = t2.parent_id START WITH ID = T.ID) branch_value FROM T CONNECT BY PRIOR t.id = t.parent_id START WITH t.parent_id IS NULL ORDER SIBLINGS BY t.id; ID SELF_VALUE BRANCH_VALUE -------------------- ---------- ------------ 1 36000 10 1000 8000 30 3000 3000 40 4000 4000 20 2000 7000 50 5000 5000 60 6000 21000 70 7000 15000 80 8000 8000 9 rows selected.
I tried to reach the same result of this query using the new syntax for subquery factoring. Any help would be really appreciated!
Hello
I think it's one of those things that CONNECT BY is better.
Here's a way to do it using a recursive clause (AND not CONNECT BY):
WITH recursive_results (ancestor_id, descendant_id, value, lvl, lineage) AS
(
SELECT id AS ancestor_id
id LIKE descendant_id
value
, 1 AS lvl
, TO_CHAR (id, "9999") AS line
T
UNION ALL
SELECT r.ancestor_id
t.id AS descendant_id
t.valeur
r.lvl + 1 AS lvl
r.lineage | ' /'
|| To_char (t.id, '9999') AS line
T
JOIN recursive_results r WE t.parent_id = r.descendant_id
)
SELECT LPAD (' ' ')
, 4 * (
SELECT MAX (lvl) - 1
OF recursive_results
WHERE descendant_id = m.ancestor_id
)
) || ancestor_id AS indented_id
SUM (CASE WHEN ancestor_id = descendant_id THEN value END) AS self_value
The amount (value) AS branch_value
OF recursive_results m
GROUP BY ancestor_id
ORDER BY)
SELECT MAX (lineage) DUNGEON (DENSE_RANK LAST ORDER BY lvl)
OF recursive_results
WHERE descendant_id = m.ancestor_id
)
;
Output (even you have):
INDENTED_ID SELF_VALUE BRANCH_VALUE
-------------------- ---------- ------------
1 36000
10-1000-8000
30 3000 3000
40 4000 4000
20-2000-7000
50 5000 5000
60 6000 21000
70-7000-15000
80-8000-8000
-
ORA-30654: 'missing DEFAULT keyword' in the recursive subquery factoring
The subquery recursive factoring works without clause CYCLE and cycle only.
When I have a cycle (uncomment SELECT 5, 2 double UNON ALL) ORACLE detects the cycle properly, but when I include the clause CYCLE I get ORA-30654.
I'm pretty shure that this statement already worked in my DB (11.2.0.3.0 - 64 bit)
CREATE TABLE temp_rsq (a,b) AS SELECT 1, 2 FROM dual UNION ALL SELECT 2, 3 FROM dual UNION ALL SELECT 3, 4 FROM dual UNION ALL SELECT 4, 5 FROM dual UNION ALL --SELECT 5, 2 FROM dual UNION ALL SELECT 5, 6 FROM dual UNION ALL SELECT 6, 7 FROM dual; -- -- -- b-> new A WITH cte ( pb, a, b, weg) AS (SELECT NULL, a, b, a FROM temp_rsq WHERE a=1 UNION ALL SELECT cte.b, n.a a, n.b, weg+n.a FROM temp_rsq n JOIN cte ON (cte.b=n.a)) SEARCH depth FIRST BY a SET abst --CYCLE a SET is_cycle to '1' DEFAULT '0' SELECT * FROM cte;
Found last al:
It does not with cusor_sharing = FORCE, only with the cursor sharing = TRUE!
For me, a very strange behavior.
-
I have a table with ID of origin and destination.
There may be a dynamic number of connections (wait is no more than 5) and the relationship is still one by one: A-> B-> C-> D
A or B or C or D can only apear in a relationship, this average-> C does not already connected to B e because.
I want to create one interviewed who receives the last values of destination and a column with the original values that are associated with this return value:
for example:
If my parameter value is D, my result will be a column of three lines: A, B, C
If my parameter value is C, my result will be a column with two lines: A, B
example:
I tried to conect by front and connect as root but could not achieve.create table test_list as ( select 32000 origin, 68200 destination from dual union all select 60000 origin, 168200 destination from dual union all select 8200 origin, 36600 destination from dual union all select 36600 origin, 8400 destination from dual union all select 8400 origin, 61800 destination from dual )
found also some articles on 'Recursive subquery factoring' but it got even worse because I couldn't make it work.
My database is 'Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64 bit Production'
So in my list:SELECT origin from test_list where origin in (select * FROM ( SELECT CONNECT_BY_ROOT destination FROM test_list CONNECT BY PRIOR origin = destination and destination =68200 ) )
32000 connects to 68200
60000 connects to 168200
8200 connects to 36600
36600 connects to 8400
8400 connects to 61800
My results are expected:
If the parameter 'VALUE_TO_SEARCH' = 68200 I wait only: 32000
If the parameter 'VALUE_TO_SEARCH' = 168200 I wait only: 60000
If the parameter 'VALUE_TO_SEARCH' = 61800 I expect: 8400,36600,8200
If the "VALUE_TO_SEARCH" parameter = 32000 I expect any results.
What would be the best method to use for optimal performance and cash is with the CONNECT_BY_ROOT and "Se CONNECT BY FRONT" that I am I did wrong here?
Best regards
Ricardo TomasHello
With the help of a WITH recursive clause:
VARIABLE value_to_search NUMBER EXEC :value_to_search := 168200; EXEC :value_to_search := 61800; -- Only the last one above matters WITH tree_results (origin, given_destination) AS ( SELECT origin, destination FROM test_list WHERE destination = :value_to_search UNION ALL SELECT t.origin , r.given_destination FROM test_list t JOIN tree_results r ON r.origin = t.destination ) SELECT * FROM tree_results ;
-
Subquery factoring and DB Link
Hello
I have a query of the form...2 node RAC Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi PL/SQL Release 10.2.0.5.0 - Production CORE 10.2.0.5.0 Production TNS for Linux: Version 10.2.0.5.0 - Production NLSRTL Version 10.2.0.5.0 - Production
This query used to work, but recently there has been a change of remote_view1, after which the query takes a long time to run.WITH temp as (select col1, col2, col3 from LOCAL_TABLE) SELECT /*+ driving_site (remote1) */ remote1.col1, remote1.col1, remote1.col1, remote1.col1, remote1.col1, remote1.col1, remote2.col1, remote2.col1, remote2.col1, remote2.col1, remote2.col1, null, null from remote_view1@dblink remote1, -- Remote View over 2 dbs remote_view2@dblink remote2 -- Remote View over 2 dbs where remote1.col1 in (select col1 from temp);
The good performing query takes 2 seconds, while providing the wrong one takes about 8 minutes.
However, if I remove the subquery factoring and include the query as a subquery it works well.
I tried to check the data from v$ sql. I saw this;SELECT /*+ driving_site (remote1) */ remote1.col1, remote1.col1, remote1.col1, remote1.col1, remote1.col1, remote1.col1, remote2.col1, remote2.col1, remote2.col1, remote2.col1, remote2.col1, null, null from remote_view1@dblink remote1, -- Remote View over 2 dbs remote_view2@dblink remote2 -- Remote View over 2 dbs where remote1.col1 in (select col1, col2, col3 from LOCAL_TABLE);
v$ SQL. Remote = 'Y' - good performance
v$ SQL. Remote = "n" - poor performance
All the world is facing this situation?
Rgds,
GuenounDo I have reason to assume that the queries executed entirely remote db have plans stored in v$ sql_plan
Right.
SQL> select /*+ domtest */ 1 from dual@domtest; 1 ---------- 1 SQL> select * from table(dbms_xplan.display_cursor); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------------- SQL_ID 9d51rf84zvt0s, child number 0 select /*+ domtest */ 1 from dual@domtest NOTE: cannot fetch plan for SQL_ID: 9d51rf84zvt0s, CHILD_NUMBER: 0 Please verify value of SQL_ID and CHILD_NUMBER; It could also be that the plan is no longer in cursor cache (check v$sql_plan) 8 rows selected. SQL> select sql_id, remote, sql_text from v$sql where sql_id = '9d51rf84zvt0s'; SQL_ID R SQL_TEXT ------------- - -------------------------------------------------- 9d51rf84zvt0s Y select /*+ domtest */ 1 from dual@domtest SQL> select * from v$sql_plan where sql_id = '9d51rf84zvt0s'; no rows selected SQL> select /*+ domtest */ 1 from dual@domtest t, dual; 1 ---------- 1 Elapsed: 00:00:00.00 SQL> select * from table(dbms_xplan.display_cursor); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------- SQL_ID d0m08znks4yak, child number 0 ------------------------------------- select /*+ domtest */ 1 from dual@domtest t, dual Plan hash value: 3754369022 ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | Inst |IN-OUT| ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 4 (100)| | | | | 1 | MERGE JOIN CARTESIAN| | 1 | 4 (0)| 00:00:01 | | | | 2 | REMOTE | DUAL | 1 | 2 (0)| 00:00:01 | DOMTE~ | R->S | | 3 | BUFFER SORT | | 1 | 2 (0)| 00:00:01 | | | | 4 | FAST DUAL | | 1 | 2 (0)| 00:00:01 | | | ------------------------------------------------------------------------------------- Remote SQL Information (identified by operation id): ---------------------------------------------------- 2 - SELECT 0 FROM "DUAL" "T" (accessing 'DOMTEST' ) 22 rows selected. Elapsed: 00:00:00.04 SQL> select sql_id, remote, sql_text from v$sql where sql_id = 'd0m08znks4yak'; SQL_ID R SQL_TEXT ------------- - -------------------------------------------------- d0m08znks4yak N select /*+ domtest */ 1 from dual@domtest t, dua SQL> select /*+ driving_site(t) */ 1 from dual@domtest t, dual; 1 ---------- 1 Elapsed: 00:00:00.00 SQL> select * from table(dbms_xplan.display_cursor); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------- SQL_ID 741u736nrk6dx, child number 0 select /*+ driving_site(t) */ 1 from dual@domtest t, dual NOTE: cannot fetch plan for SQL_ID: 741u736nrk6dx, CHILD_NUMBER: 0 Please verify value of SQL_ID and CHILD_NUMBER; It could also be that the plan is no longer in cursor cache (check v$sql_plan) 8 rows selected. Elapsed: 00:00:00.01 SQL> select sql_id, remote, sql_text from v$sql where sql_id = '741u736nrk6dx'; SQL_ID R SQL_TEXT ------------- - -------------------------------------------------- 741u736nrk6dx Y select /*+ driving_site(t) */ 1 from dual@domtest t, dual Elapsed: 00:00:00.00 SQL> SQL> select * from v$sql_plan where sql_id = '741u736nrk6dx'; no rows selected Elapsed: 00:00:00.01 SQL>
Published by: Dom Brooks on August 21, 2012 13:05
-
I'm trying to learn more about the recursive subquery, but I'm stuck with this one. For each word, recursively remove 1, 2, 3... n characters of the word for all possible combinations. The word length is variable. For example, would be the expected result for the words 'abcd' and '123'. A PLSQL solution would be better?
ABCD:
1 deleted character: bcd, CDA, abd, abc
2 deleted characters: cd, bd, BC., ad, ac, ab
3 characters deleted: d, c, b, a
4 removed characters: null
123:
1 deleted character: 12, 13 and 23
2 deleted characters: 1, 2, and 3
3 deleted characters: null
Hello
Here's a solution that makes everything you asked for, including characters removed (in order or appearance).
As I used SYS_CONNECT_BY_PATH for a concatenated string of all of the included characters, so I used SYS_CONNECT_BY_PATH for a concatenated string of all characters between those included.
WITH single_characters (c, n word) AS
(
SELECT Word
, NULL AS c
, 1 AS n
The CBC
UNION ALL
SELECT Word
SUBSTR (word, n - 1) c
, n + 1 AS n
OF single_characters
WHERE n<= length="">=>
)
SELECT Word
REPLACE (SYS_CONNECT_BY_PATH (c, "ab")
, 'ab '.
) AS comb
LENGTH (word) + 1 - LEVEL AS num_removed
REPLACE (SYS_CONNECT_BY_PATH (SUBSTR (Word
N ADVANCE
, n - (n + 1 PREREQUISITE)
)
, "ba".
)
, "ba".
) || SUBSTR (Word, n) AS deleted
OF single_characters
START WITH n = 1
CONNECT BY NOCYCLE Word = Word PREREQUISITE
AND n > PREREQUISITE n
AND LEVEL<= length="">=>
ORDER BY word
LEVEL DESC
deleted
;
Output:
NUM_REMOVED DELETED WORD COMB
---------- ---------- ----------- -------
123 23 1 1
123 13 1 2
123 12 1 3
123 3 2 12
123 2 2 13
123 1 2 23
123 3 123
ABCD bcd 1A
ABCD DCO 1 b
Abu abd 1 c
ABCD abc 1 d
AB cd 2 ABCD
ABCD 2 ac comics
ABCD BC 2
ABCD ad 2 BC.
ABCD ac 2 bd
ABCD ab 2 cd
ABCD d 3 abc
ABCD c 3 abd
ABCD b 3 CDA
ABCD has 3 bcd
ABCD ABCD 4
lee le 1 e
lee le 1 e
lee ee 1 l
lee l 2 ee
lee e 2 le
lee e 2 le
lee 3 lee
With the exception of the order of the rows in the result, it's exactly what you asked in response #2.
If the order of the rows is important, I'm sure we can get it exactly as you wish; just explain exactly how it needs to be sorted.
-
disadvantages of subquery factoring (with clause)
Hi all
What are disadvantages of subquery factoring (with clause) (if any)?Features have no disadvantages, disadvantages depends on how use you them...
-
Subquery factoring and materialize Hint
In the example given the sub query returns just one line because of the max aggregate function. This by making a With clause that will be of any benefit? Also I assume / understand that factoring of subquery would be really useful when we try to do a sub query that returns multiple rows in a clause. Is my right to intrepration?WITH t AS (SELECT MAX (lDATE) tidate FROM rate_Master WHERE Code = 'G' AND orno > 0 AND TYPE = 'L' AND lDATE <= ':entereddate') SELECT DECODE (:p1, 'B', RateB, 'S', RateS, Rate) FROM rate_Master, t WHERE Code = 'G' AND orno > 0 AND TYPE = 'L' AND NVL (lDATE, SYSDATE) = tidate;
Then add the / * + Materialize * / reference to a query with is required or the optimizer itself will do and perform a transformation of the temporary table. In my example, I have to give the hint in the query. Please discuss and help
Thanks in advance.ramarun wrote:
WITH t AS (SELECT MAX (lDATE) tidate FROM rate_Master WHERE Code = 'G' AND orno > 0 AND TYPE = 'L' AND lDATE <= ':entereddate') SELECT DECODE (:p1, 'B', RateB, 'S', RateS, Rate) FROM rate_Master, t WHERE Code = 'G' AND orno > 0 AND TYPE = 'L' AND NVL (lDATE, SYSDATE) = tidate;
In the example given the sub query returns just one line because of the max aggregate function. This by making a With clause that will be of any benefit? Also I assume / understand that factoring of subquery would be really useful when we try to do a sub query that returns multiple rows in a clause. Is my right to intrepration?
Not quite.
The subquery factoring should be used when you want to use the subquery results more than once in your query. So if you write a regular SQL statement, but find that it is necessary to write the same subquery more than once inside, then you can factor on this subquery using the WITH clause, so that it is executed once, and the results may then be referenced several times in the main query. This is what gives a performance advantage in many cases.Then add the / * + Materialize * / reference to a query with is required or the optimizer itself will do and perform a transformation of the temporary table. In my example, I have to give the hint in the query. Please discuss and help
As mentioned the suspicion of materialization is not documented so should not be used in production code. Personally, I found that it can add significant performance gain of a weighted subquery where this subquery causes a large amount of data. Don't know why the optimizer is not always materialize subqueries by default but... not really looked inside a lot.
-
Subquery factoring clause and the temporary table
Is it possible (probably a hint) to specify the Oracle to create a temporary table in subquery factoring (with...) clause?
So if I have a query
How can I do Oracle to generate a plan that creates a temporary table for t1 (and not using t1 as inline view)?with t1 as (select ...) select ...
Hello
use the indicator to materialize:
with t1 as (select /*+ materialize */ ...) select ...
Herald tiomela
http://htendam.WordPress.com -
Subquery Factoring - cardinality estimate good but bad sql response times
This is Exadata 11.2.0.4.0 database, all tables have statistics of up to date. Cardinality estimation is good compared to the actual cardinality. It is a way to tune this sql to reduce its response time.
Sorry for the long sql and the execution plan.
WITH SUBWITH0 AS (SELECT D1.c1 AS c1 FROM ( (SELECT D1.c1 AS c1 FROM (SELECT DISTINCT T7171.CH_ID_SYM AS c1 FROM DW.TM_R_REP T7171 WHERE ( T7171.CHILD_REP_ID = 939 ) ) D1 UNION SELECT D1.c1 AS c1 FROM (SELECT DISTINCT T7167.MEMBER_KEY_SYM AS c1 FROM DW.PC_T_REP T7167 WHERE ( T7167.ANCESTOR_KEY = 939 ) ) D1 ) ) D1 ), SUBWITH1 AS (SELECT D1.c1 AS c1 FROM ( (SELECT D1.c1 AS c1 FROM (SELECT DISTINCT T7171.CH_ID_SYM AS c1 FROM DW.TM_R_REP T7171 WHERE ( T7171.CHILD_REP_ID = 939 ) ) D1 UNION SELECT D1.c1 AS c1 FROM (SELECT DISTINCT T7167.MEMBER_KEY_SYM AS c1 FROM DW.PC_T_REP T7167 WHERE ( T7167.ANCESTOR_KEY = 939 ) ) D1 ) ) D1 ), SUBWITH2 AS (SELECT DISTINCT T7171.CH_ID_SYM AS c1 FROM ( DW.PC_T_REP T7167 LEFT OUTER JOIN DW.TM_R_REP T7171 ON T7167.ANCESTOR_KEY = T7171.CHILD_REP_ID AND T7167.SALESYEARMONTH = T7171.SALES_YEAR_MONTH) LEFT OUTER JOIN DW.TM_REP T6715 ON T7171.CHILD_REP_ID_N = T6715.REP_ID WHERE ( CASE WHEN T7171.CHILD_REP_ID_N LIKE '9999%' THEN concat(concat('UNASSIGNED', lpad(' ', 2)), CAST(T7167.TERRITORY_ID AS VARCHAR ( 20 ) )) ELSE concat(concat(concat(concat(T6715.FIRST_NAME, lpad(' ', 2)), T6715.MIDDLE_NAME), lpad(' ', 2)), T6715.LAST_NAME) END = 'JOES CRAMER' AND T7171.SALES_YEAR_MONTH BETWEEN '201505' AND '201505' AND T7171.CH_ID_SYM IN (SELECT DISTINCT D1.c1 AS c1 FROM SUBWITH0 D1 ) ) ), SUBWITH3 AS (SELECT MEMBER_KEY_SYM AS c1 FROM DW.PC_T_REP T7167 WHERE ( IS_LEAF = 1 ) ), SAWITH0 AS (SELECT DISTINCT CASE WHEN T7171.CHILD_REP_ID_N LIKE '9999%' THEN concat(concat('UNASSIGNED', lpad(' ', 2)), CAST(T7167.TERRITORY_ID AS VARCHAR ( 20 ) )) ELSE concat(concat(concat(concat(T6715.FIRST_NAME, lpad(' ', 2)), T6715.MIDDLE_NAME), lpad(' ', 2)), T6715.LAST_NAME) END AS c1, T6715.REP_NUM AS c2, T7171.SALES_YEAR_MONTH AS c3, T7315.MONTH_NUMERIC AS c4, CASE WHEN T7171.CH_ID_SYM IN (SELECT D1.c1 AS c1 FROM SUBWITH3 D1 ) THEN 1 ELSE 0 END AS c5, CAST(T7171.PARENT_REP_ID AS CHARACTER ( 30 ) ) AS c6, T7171.CH_ID_SYM AS c7, T7171.PARENT_REP_ID_SYM AS c8 FROM DW.TIM_MON T7315 , ( ( DW.PC_T_REP T7167 LEFT OUTER JOIN ( (SELECT TO_NUMBER(TO_CHAR(L_OPP.CloseDate,'YYYYMM')) AS Sales_Year_Month, Tm_Rep.Rep_Id AS Rep_Id, L_OPP.Account_Name__C AS Account_Name__C, L_OPP.Closedate AS Closedate, L_OPP.Forecastcategory AS Forecastcategory, L_OPP.Forecastcategoryname AS Forecastcategoryname, L_User.NAME AS Opp_Owner_S_Sales_Org__C, L_OPP.Opportunity_Id__C AS Opportunity_Id__C, L_OPP.Renewal_Date__C AS Renewal_Date__C, L_OPP.Total_Incremental__C AS Total_Incremental__C, L_OPP.Offer_Code__C AS Offer_Code__C, L_OPP.ID AS Opportunity_ID, L_OPP.TERRITORYID AS TERRITORYID, L_OPP.ACCOUNTID AS ACCOUNTID, L_OPP.OWNERID AS OWNERID, L_OPP.TOTAL_RENEWAL__C AS TOTAL_RENEWAL__C, L_OPP.NAME AS NAME, L_OPP.STAGENAME AS STAGE_NAME, L_OPP.STAGE_DESCRIPTION__C AS STAGE_DESCRIPTION, NVL( CASE WHEN L_OPP.Forecastcategory = 'Closed' AND( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN L_OPP.Total_Incremental__C END , 0) AS Closed_Oppurtunity, CASE WHEN L_OPP.Forecastcategory = 'Closed' AND ( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN 'Closed_Oppurtunity_Drill' END AS Closed_Oppurtunity_Drill, NVL( CASE WHEN L_OPP.Forecastcategoryname IN ('Pipeline', 'Potential', 'Commit') AND ( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN L_OPP.Total_Incremental__C END , 0) AS OPEN_Oppurtunity, CASE WHEN L_OPP.Forecastcategoryname IN ('Pipeline', 'Potential', 'Commit') AND ( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN 'OPEN_Oppurtunity_Drill' END AS OPEN_Oppurtunity_Drill, NVL( CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year1_Closed_Opp, CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN 'Renewal_Year1_Closed_Opp_Drill' END AS Renewal_Year1_Closed_Opp_Drill, NVL( CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year1_OPEN_Opp, CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN 'Renewal_Year1_OPEN_Opp_Drill' END AS Renewal_Year1_OPEN_Opp_Drill, NVL( CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year2_Closed_Opp, CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN 'Renewal_Year2_Closed_Opp_Drill' END AS Renewal_Year2_Closed_Opp_Drill, NVL( CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year2_OPEN_Opp, CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN 'Renewal_Year2_OPEN_Opp_Drill' END AS Renewal_Year2_OPEN_Opp_Drill FROM DW.OPP_C_DIM RIGHT OUTER JOIN RT.L_OPP ON (TO_CHAR(OPP_C_DIM.OFFER_CODE) =TO_CHAR(L_OPP.Offer_Code__C) AND (TO_CHAR(L_OPP.CloseDate,'YYYYMM')) = TO_CHAR(OPP_C_DIM.PERIOD)) LEFT OUTER JOIN RT.L_User ON (L_OPP.Ownerid=L_User.Id) LEFT OUTER JOIN DW.Tm_Rep ON (Tm_Rep.Rep_Num='0' ||L_User.Rep_Employee_Number__C) )) T774110 ON T7167.MEMBER_KEY = T774110.Rep_Id AND T7167.SALESYEARMONTH = T774110.Sales_Year_Month) LEFT OUTER JOIN DW.TM_R_REP T7171 ON T7167.ANCESTOR_KEY = T7171.CHILD_REP_ID AND T7167.SALESYEARMONTH = T7171.SALES_YEAR_MONTH) LEFT OUTER JOIN DW.TM_REP T6715 ON T7171.CHILD_REP_ID_N = T6715.REP_ID WHERE ( T774110.Sales_Year_Month = T7315.YEAR_MONTH AND T7171.CH_ID_SYM IN (SELECT DISTINCT D1.c1 AS c1 FROM SUBWITH2 D1 ) AND T7171.SALES_YEAR_MONTH BETWEEN '201505' AND '201505' AND T7171.CH_ID_SYM IN (SELECT DISTINCT D1.c1 AS c1 FROM SUBWITH1 D1 ) ) ), SAWITH1 AS (SELECT SUM(T774110.Renewal_Year2_OPEN_Opp) AS c9, SUM(T774110.Renewal_Year2_Closed_Opp) AS c10, SUM(T774110.Renewal_Year1_OPEN_Opp) AS c11, SUM(T774110.Renewal_Year1_Closed_Opp) AS c12, SUM(T774110.OPEN_Oppurtunity) AS c13, SUM(T774110.Closed_Oppurtunity) AS c14, T7315.MONTH_NUMERIC AS c15, T7171.CH_ID_SYM AS c16 FROM DW.TIM_MON T7315 , ( RT.L_ACCOUNT T765190 LEFT OUTER JOIN ( DW.PC_T_REP T7167 LEFT OUTER JOIN ( (SELECT TO_NUMBER(TO_CHAR(L_OPP.CloseDate,'YYYYMM')) AS Sales_Year_Month, Tm_Rep.Rep_Id AS Rep_Id, L_OPP.Account_Name__C AS Account_Name__C, L_OPP.Closedate AS Closedate, L_OPP.Forecastcategory AS Forecastcategory, L_OPP.Forecastcategoryname AS Forecastcategoryname, L_User.NAME AS Opp_Owner_S_Sales_Org__C, L_OPP.Opportunity_Id__C AS Opportunity_Id__C, L_OPP.Renewal_Date__C AS Renewal_Date__C, L_OPP.Total_Incremental__C AS Total_Incremental__C, L_OPP.Offer_Code__C AS Offer_Code__C, L_OPP.ID AS Opportunity_ID, L_OPP.TERRITORYID AS TERRITORYID, L_OPP.ACCOUNTID AS ACCOUNTID, L_OPP.OWNERID AS OWNERID, L_OPP.TOTAL_RENEWAL__C AS TOTAL_RENEWAL__C, L_OPP.NAME AS NAME, L_OPP.STAGENAME AS STAGE_NAME, L_OPP.STAGE_DESCRIPTION__C AS STAGE_DESCRIPTION, NVL( CASE WHEN L_OPP.Forecastcategory = 'Closed' AND( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN L_OPP.Total_Incremental__C END , 0) AS Closed_Oppurtunity, CASE WHEN L_OPP.Forecastcategory = 'Closed' AND ( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN 'Closed_Oppurtunity_Drill' END AS Closed_Oppurtunity_Drill, NVL( CASE WHEN L_OPP.Forecastcategoryname IN ('Pipeline', 'Potential', 'Commit') AND ( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN L_OPP.Total_Incremental__C END , 0) AS OPEN_Oppurtunity, CASE WHEN L_OPP.Forecastcategoryname IN ('Pipeline', 'Potential', 'Commit') AND ( OPP_C_DIM.OPPORTUNITIES_GROUP IS NULL ) THEN 'OPEN_Oppurtunity_Drill' END AS OPEN_Oppurtunity_Drill, NVL( CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year1_Closed_Opp, CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN 'Renewal_Year1_Closed_Opp_Drill' END AS Renewal_Year1_Closed_Opp_Drill, NVL( CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year1_OPEN_Opp, CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL1' THEN 'Renewal_Year1_OPEN_Opp_Drill' END AS Renewal_Year1_OPEN_Opp_Drill, NVL( CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year2_Closed_Opp, CASE WHEN L_OPP.Forecastcategory = 'Closed' AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN 'Renewal_Year2_Closed_Opp_Drill' END AS Renewal_Year2_Closed_Opp_Drill, NVL( CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN L_OPP.TOTAL_RENEWAL__C END , 0) AS Renewal_Year2_OPEN_Opp, CASE WHEN L_OPP.Forecastcategory IN ('Pipeline', 'Forecast', 'BestCase') AND OPP_C_DIM.OPPORTUNITIES_GROUP ='RENEWAL2' THEN 'Renewal_Year2_OPEN_Opp_Drill' END AS Renewal_Year2_OPEN_Opp_Drill FROM DW.OPP_C_DIM RIGHT OUTER JOIN RT.L_OPP ON (TO_CHAR(OPP_C_DIM.OFFER_CODE) =TO_CHAR(L_OPP.Offer_Code__C) AND (TO_CHAR(L_OPP.CloseDate,'YYYYMM')) = TO_CHAR(OPP_C_DIM.PERIOD)) LEFT OUTER JOIN RT.L_User ON (L_OPP.Ownerid=L_User.Id) LEFT OUTER JOIN DW.Tm_Rep ON (Tm_Rep.Rep_Num='0' ||L_User.Rep_Employee_Number__C) )) T774110 ON T7167.MEMBER_KEY = T774110.Rep_Id AND T7167.SALESYEARMONTH = T774110.Sales_Year_Month) ON T765190.ID = T774110.ACCOUNTID) LEFT OUTER JOIN DW.TM_R_REP T7171 ON T7167.ANCESTOR_KEY = T7171.CHILD_REP_ID AND T7167.SALESYEARMONTH = T7171.SALES_YEAR_MONTH WHERE ( T774110.Sales_Year_Month = T7315.YEAR_MONTH AND T7171.CH_ID_SYM IN (SELECT DISTINCT D1.c1 AS c1 FROM SUBWITH2 D1 ) AND T7171.SALES_YEAR_MONTH BETWEEN '201505' AND '201505' AND T7171.CH_ID_SYM IN (SELECT DISTINCT D1.c1 AS c1 FROM SUBWITH1 D1 ) ) GROUP BY T7171.CH_ID_SYM, T7315.MONTH_NUMERIC ) SELECT DISTINCT D2.c9 AS c1, D2.c10 AS c2, D2.c11 AS c3, D2.c12 AS c4, D2.c13 AS c5, D2.c14 AS c6, D1.c1 AS c7, D1.c2 AS c8, D1.c3 AS c9, D1.c4 AS c10, D1.c5 AS c11, D1.c6 AS c12, D1.c7 AS c13, D1.c8 AS c14 FROM SAWITH0 D1 INNER JOIN SAWITH1 D2 ON SYS_OP_MAP_NONNULL(D2.c15) = SYS_OP_MAP_NONNULL(D1.c4) AND SYS_OP_MAP_NONNULL(D2.c16) = SYS_OP_MAP_NONNULL(D1.c7) ORDER BY c10, c13
SQL in real time, followed by the details with the Predicate Section of dbms_xplan.display_cursor shot
Global stats
==============================================================================================================================
| Elapsed. CPU | E/S | Request | Cluster | Others | Pick up | Buffer | Read | Read | Write | Write | Cell |
| Time (s) | Time (s) | Waiting (s) | Waiting (s) | Waiting (s) | Waiting (s) | Calls | Gets | Reqs | Bytes | Reqs | Bytes | Unloading |
==============================================================================================================================
| 152. 146. 3.73 | 0.08 | 0.04 | 2.04 | 2. 16 M | 5223. 1 GB | 1. 200KB | 95,11% |
==============================================================================================================================
SQL details surveillance Plan (Plan hash value = 442312180)
===============================================================================================================================================================================================================================================
| ID | Operation | Name | Lines | Cost | Time | Start | Execs | Lines | Read | Read | Cell | MEM | Activity | Activity detail |
| | | | (Estimated) | | Active (s) | Active | | (Real) | Reqs | Bytes | Unloading | (Max) | (%) | (Number of samples).
===============================================================================================================================================================================================================================================
| 0 | SELECT STATEMENT | | | | 1. 152. 1. 0 | | | | | 0.65 | Cpu (1) |
| 1. RANGE OF PARTITION ALL THE | | 1. 3892 | | | 1. | | | | | | |
| 2. ACCESS STORAGE FULL FIRST RANKS TABLE. PC_T_REP | 1. 3892 | | | 37. | 74. 19 MB | 78.45% | 17 M | | |
| 3. TRANSFORMATION OF THE TEMPORARY TABLE. | | | 1. 152. 1. 1. | | | | | |
| 4. LOAD SELECT ACE | | | | 1. + 5 | 1. 1. | | | 278K | | |
| 5. VIEW | | 105. 3980 | 1. + 5 | 1. 13637 | | | | | | |
| 6. SORT UNIQUE | | 105. 3980 | 1. + 5 | 1. 13637 | | | | 757K | | |
| 7. UNION-ALL | | | | 1. + 5 | 1. 14033. | | | | | |
| 8. STORE TABLE FULL ACCESS | TM_R_REP | 22. 88. 1. + 5 | 1. 36. | | | | | |
| 9. RANGE OF PARTITION ALL THE | | 83. 3890. 1. + 5 | 1. 13997. | | | | | |
| 10. STORE TABLE FULL ACCESS | PC_T_REP | 83. 3890. 6. + 0 | 37. 13997. | | | 2 M | 0.65 | Smart cell table scan (1) |
| 11. LOAD SELECT ACE | | | | 1. + 5 | 1. 1. | | | 278K | | |
| 12. HASH UNIQUE | | 1. 4166. 1. + 5 | 1. 1. | | | 479K | | |
| 13. HASH JOIN | | 1. 4165 | 1. + 5 | 1. 444. | | | 1 M | | |
| 14. JOIN FILTER PART CREATE | : BF0000 | 3. 4075 | 1. + 5 | 1. 549. | | | | | |
| 15. OUTER HASH JOIN | | 3. 4075 | 1. + 5 | 1. 549. | | | 1 M | | |
| 16. HASH JOIN | | 3. 4068 | 1. + 5 | 1. 549. | | | 2 M | | |
| 17. VIEW | | 105. 3980 | 1. + 5 | 1. 13637 | | | | | | |
| 18. SORT UNIQUE | | 105. 3980 | 1. + 5 | 1. 13637 | | | | 757K | | |
| 19. UNION-ALL | | | | 1. + 5 | 1. 14033. | | | | | |
| 20. STORE TABLE FULL ACCESS | TM_R_REP | 22. 88. 1. + 5 | 1. 36. | | | | | |
| 21. RANGE OF PARTITION ALL THE | | 83. 3890. 1. + 5 | 1. 13997. | | | | | |
| 22. STORE TABLE FULL ACCESS | PC_T_REP | 83. 3890. 1. + 5 | 37. 13997. | | | 2 M | | |
| 23. STORE TABLE FULL ACCESS | TM_R_REP | 1884 | 88. 1. + 5 | 1. 1929 | | | | | | |
| 24. STORE TABLE FULL ACCESS | TM_REP | 7136 | 7. 1. + 5 | 1. 7137 | | | | | | |
| 25. RANGE OF SINGLE PARTITION | | 7449. 90. 1. + 5 | 1. 7449. | | | | | |
| 26. STORE TABLE FULL ACCESS | PC_T_REP | 7449. 90. 1. + 5 | 1. 7449. | | | | | |
| 27. SORT UNIQUE | | 1. 26032 | 1. 152. 1. 1. | | | 2048 | | |
| 28. OUTER HASH JOIN | | 1. 26031 | 72. + 81 | 1. 8238 | | | | 4 M | | |
| 29. FILTER | | | | 74. + 79 | 1. 8238 | | | | | 1.96 | Cpu (3) |
| 30. NESTED EXTERNAL LOOPS | | 1. 26027 | 72. + 81 | 1. 15 M | | | | | 3.27 | Cpu (5) |
| 31. HASH JOIN | | 1. 26026 | 72. + 81 | 1. 15 M | | | | 447K | 18.95 | Cpu (29) |
| 32. OUTER HASH JOIN | | 1. 13213 | 1. + 81 | 1. 332. | | | 452K | | |
| 33. HASH JOIN | | 1. 13206 | 1. + 81 | 1. 332. | | | 1 M | | |
| 34. HASH JOIN | | 1. 13199. 1. + 81 | 1. 444. | | | 434K | | |
| 35. HASH JOIN | | 1. 13197. 1. + 81 | 1. 444. | | | 290K | | |
| 36. JOIN CREATE FILTER | : BF0000 | 1. 13195. 1. + 81 | 1. 444. | | | | | |
| 37. HASH JOIN | | 1. 13195. 1. + 81 | 1. 444. | | | 2 M | | |
| 38. THE CARTESIAN MERGE JOIN. | 27. 13107 | 1. + 81 | 1. 7449. | | | | | |
| 39. HASH JOIN | | 1. 13017. 77. + 5 | 1. 1. | | | 750K | | |
| 40. STORE TABLE FULL ACCESS | TIM_MON | 1. 4. 1. + 5 | 1. 1. | | | | | |
| 41. VIEW | | 1. 13013. 1. + 81 | 1. 1. | | | | | |
| 42. HASH GROUP BY. | 1. 13013. 1. + 81 | 1. 1. | | | 482K | | |
| 43. OUTER HASH JOIN | | 1. 13012. 77. + 5 | 1. 8238 | | | | 4 M | | |
| 44. NESTED LOOPS | | 1. 13008. 77. + 5 | 1. 8238 | | | | | | |
| 45. FILTER | | | | 77. + 5 | 1. 8238 | | | | | 2.61 | Cpu (4) |
| 46. NESTED EXTERNAL LOOPS | | 1. 13007. 77. + 5 | 1. 15 M | | | | | 4.58. Cpu (7) |
| 47. HASH JOIN | | 1. 13006. 77. + 5 | 1. 15 M | | | | 424K | 11.76. Cpu (18) |
| 48. HASH JOIN | | 1. 193. 1. + 5 | 1. 332. | | | 1 M | | |
| 49. HASH JOIN | | 1. 186. 1. + 5 | 1. 444. | | | 420K | | |
| 50. HASH JOIN | | 4. 184. 1. + 5 | 1. 444. | | | 290K | | |
| 51. JOIN CREATE FILTER | : BF0002 | 1. 94. 1. + 5 | 1. 1. | | | | | |
| 52. JOIN FILTER PART CREATE | : BF0001 | 1. 94. 1. + 5 | 1. 1. | | | | | |
| 53. HASH JOIN | | 1. 94. 1. + 5 | 1. 1. | | | 290K | | |
| 54. JOIN CREATE FILTER | : BF0003 | 1. 6. 1. + 5 | 1. 1. | | | | | |
| 55. THE CARTESIAN MERGE JOIN. | 1. 6. 1. + 5 | 1. 1. | | | | | |
| 56. STORE TABLE FULL ACCESS | TIM_MON | 1. 4. 1. + 5 | 1. 1. | | | | | |
| 57. KIND OF BUFFER. | 1. 2. 1. + 5 | 1. 1. | | | 2048 | | |
| 58. VIEW | VW_NSO_1 | 1. 2. 1. + 5 | 1. 1. | | | | | |
| 59. UNIQUE HASH | | 1. | 1. + 5 | 1. 1. | | | 485K | | |
| 60. VIEW | | 1. 2. 1. + 5 | 1. 1. | | | | | |
| 61. STORE TABLE FULL ACCESS | SYS_TEMP_0FD9D71E1_B445AE36 | 1. 2. 1. + 5 | 1. 1. | | | | | |
| 62. USE OF JOIN FILTER | : BF0003 | 1884 | 88. 1. + 5 | 1. 1. | | | | | |
| 63. STORE TABLE FULL ACCESS | TM_R_REP | 1884 | 88. 1. + 5 | 1. 1. | | | | | |
| 64. USE OF JOIN FILTER | : BF0002 | 7449. 90. 1. + 5 | 1. 444. | | | | | |
| 65. RANGE OF SINGLE PARTITION | | 7449. 90. 5. + 1 | 1. 444. | | | | 0.65 | Cpu (1) |
| 66. STORE TABLE FULL ACCESS | PC_T_REP | 7449. 90. 1. + 5 | 1. 444. | | | | | |
| 67. VIEW | | 105. 2. 1. + 5 | 1. 13637 | | | | | | |
| 68. STORE TABLE FULL ACCESS | SYS_TEMP_0FD9D71E0_B445AE36 | 105. 2. 1. + 5 | 1. 13637 | | | | | | |
| 69. STORE TABLE FULL ACCESS | TM_REP | 7136 | 7. 1. + 5 | 1. 7137 | | | | | | |
| 70. STORE TABLE FULL ACCESS | L_OP | 19382 | 12813 | 77. + 5 | 1. 43879 | 565. 551 MB | 98.18% | 15 M | | |
| 71. TABLE ACCESS BY INDEX ROWID | L_US | 1. 1. 79. + 3 | 15 M | 15 M | 26. 208KO | | | 19.61 | Cpu (30) |
| 72. INDEX UNIQUE SCAN | L_US_PK | 1. | 77. + 5 | 15 M | 15 M | 2. 16384. | | 9 h 15 | Cpu (14) |
| 73. INDEX UNIQUE SCAN | L_A_PK | 1. 1. 151. + 2 | 8238 | 8238 | 3269 | 26 MB | | | 2.61 | Cpu (1) |
| | | | | | | | | | | | | | | monobloc cell physical read (3) |
| 74. STORE TABLE FULL ACCESS | OPP_C_DIM | 2304 | 4. 1. + 81 | 1. 2304 | 3. 112 KB | | | | |
| 75. KIND OF BUFFER. | 7449. 13107 | 1. + 81 | 1. 7449. | | | 370K | | |
| 76. RANGE OF SINGLE PARTITION | | 7449. 90. 1. + 81 | 1. 7449. | | | | | |
| 77. STORE TABLE FULL ACCESS | PC_T_REP | 7449. 90. 1. + 81 | 1. 7449. | | | | | |
| 78. STORE TABLE FULL ACCESS | TM_R_REP | 1884 | 88. 1. + 81 | 1. 1929 | | | | | | |
| 79. VIEW | | 1. 2. 1. + 81 | 1. 1. | | | | | |
| 80. USE OF JOIN FILTER | : BF0000 | 1. 2. 1. + 81 | 1. 1. | | | | | |
| 81. STORE TABLE FULL ACCESS | SYS_TEMP_0FD9D71E1_B445AE36 | 1. 2. 1. + 81 | 1. 1. | | | | | |
| 82. VIEW | | 105. 2. 1. + 81 | 1. 13637 | | | | | | |
| 83. STORE TABLE FULL ACCESS | SYS_TEMP_0FD9D71E0_B445AE36 | 105. 2. 1. + 81 | 1. 13637 | | | | | | |
| 84. STORE TABLE FULL ACCESS | TM_REP | 7136 | 7. 1. + 81 | 1. 7137 | | | | | | |
| 85. STORE TABLE FULL ACCESS | TM_REP | 7136 | 7. 1. + 81 | 1. 7137 | | | | | | |
| 86. STORE TABLE FULL ACCESS | L_OP | 19382 | 12813 | 72. + 81 | 1. 43879 | 593. 577 MB | 98,44% | 15 M | | |
| 87. TABLE ACCESS BY INDEX ROWID | L_US | 1. 1. 72. + 81 | 15 M | 15 M | | | | | 13.73. Cpu (21) |
| 88. INDEX UNIQUE SCAN | L_US_PK | 1. | 73. + 80 | 15 M | 15 M | | | | | 9.80 | Cpu (15) |
| 89. STORE TABLE FULL ACCESS | OPP_C_DIM | 2304 | 4. 1. 152. 1. 2304 | | | | | | |
===============================================================================================================================================================================================================================================
Information of predicates (identified by the operation identity card):
---------------------------------------------------
2. (("MEMBER_KEY_SYM" =: B1 ET "IS_LEAF" = 1) filter)
8 - storage("T7171".") CHILD_REP_ID "= 939)
filter ("T7171". ("CHILD_REP_ID" = 939)
10 - storage("T7167".") ANCESTOR_KEY "= 939)
filter ("T7167". ("ANCESTOR_KEY" = 939)
13 - access("T7167".") SALESYEARMONTH "= 'T7171'." SALES_YEAR_MONTH' AND 'T7167 '. "ANCESTOR_KEY"= "T7171". ("' CHILD_REP_ID")
filter (CASE WHEN TO_CHAR ("T7171". "CHILD_REP_ID_N") AS 9999% ' THEN 'ALL UNASSIGNED' | " CAST ("T7167". ("TERRITORY_ID" AS A VARCHAR (20)) ELSE 'T6715 '. "" NAME "| "
'||" T6715 ". "" MIDDLE_NAME "| " '||" T6715 ". ("" LAST_NAME "END ="JOES CRAMER")
15 - access("T7171".") CHILD_REP_ID_N "= 'T6715'." REP_ID")
16 - access("T7171".") CH_ID_SYM '= 'D1'.' C1")
20 - storage("T7171".") CHILD_REP_ID "= 939)
filter ("T7171". ("CHILD_REP_ID" = 939)
22 - storage("T7167".") ANCESTOR_KEY "= 939)
filter ("T7167". ("ANCESTOR_KEY" = 939)
23 - storage("T7171".") SALES_YEAR_MONTH "= 201505)
filter ("T7171". ("SALES_YEAR_MONTH" = 201505)
26 - storage("T7167".") SALESYEARMONTH "= 201505)
filter ("T7167". ("SALESYEARMONTH" = 201505)
28 - access (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM") = TO_CHAR ("OPP_C_DIM". " PERIOD") AND
TO_CHAR ("OPP_C_DIM". "OFFER_CODE") = "L_OP". ("' OFFER_CODE__C")
29 - filter("TM_REP".") REP_NUM "=" 0"|" » « « « L_US «. » REP_EMPLOYEE_NUMBER__C')
31 - access("T7315".") YEAR_MONTH «= TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP".» CLOSEDATE"),"YYYYMM")) AND
'T7167 '. «SALESYEARMONTH «= TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP".» (((("" CLOSEDATE "),"YYYYMM")))
32 - access("T7171".") CHILD_REP_ID_N "= 'T6715'." REP_ID")
33 - access("T7167".") MEMBER_KEY "=" TM_REP. " ("" REP_ID ")
34 - access("T7171".") CH_ID_SYM '= 'D1'.' C1")
35 - access("T7171".") CH_ID_SYM '= 'D1'.' C1")
37 - access (SYS_OP_MAP_NONNULL ("D2". "C16") = SYS_OP_MAP_NONNULL ("T7171". " CH_ID_SYM") AND"T7167 ". "SALESYEARMONTH"= "T7171". "" SALES_YEAR_MONTH "AND
'T7167 '. "ANCESTOR_KEY"= "T7171". ("' CHILD_REP_ID")
39 - access (SYS_OP_MAP_NONNULL ("D2". "C15") = SYS_OP_MAP_NONNULL ("T7315". " MONTH_NUMERIC'))
40 - storage("T7315".") YEAR_MONTH "= 201505)
filter ("T7315". ("YEAR_MONTH" = 201505)
43 - access (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM") = TO_CHAR ("OPP_C_DIM". " PERIOD") AND
TO_CHAR ("OPP_C_DIM". "OFFER_CODE") = "L_OP". ("' OFFER_CODE__C")
45 - filter("TM_REP".") REP_NUM "=" 0"|" » « « « L_US «. » REP_EMPLOYEE_NUMBER__C')
47 - access("T7315".") YEAR_MONTH «= TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP".» CLOSEDATE"),"YYYYMM")) AND
'T7167 '. «SALESYEARMONTH «= TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP".» (((("" CLOSEDATE "),"YYYYMM")))
48 - access("T7167".") MEMBER_KEY "=" TM_REP. " ("" REP_ID ")
49 - access("T7171".") CH_ID_SYM '= 'D1'.' C1")
50 - access("T7167".") SALESYEARMONTH "= 'T7171'." SALES_YEAR_MONTH' AND 'T7167 '. "ANCESTOR_KEY"= "T7171". ("' CHILD_REP_ID")
53 - access("T7171".") CH_ID_SYM "=" C1")
56 - storage("T7315".") YEAR_MONTH "= 201505)
filter ("T7315". ("YEAR_MONTH" = 201505)
63 - storage (("T7171". "SALES_YEAR_MONTH" = 201505 AND SYS_OP_BLOOM_FILTER (: BF0000, "T7171" ".") CH_ID_SYM')))
filter (("T7171". "SALES_YEAR_MONTH" = 201505 AND SYS_OP_BLOOM_FILTER (: BF0000, "T7171" ".") CH_ID_SYM')))
66 - storage (("T7167". "SALESYEARMONTH" = 201505 AND SYS_OP_BLOOM_FILTER (: BF0000, "T7167" ".") SALESYEARMONTH', 'T7167 '. ((("" ANCESTOR_KEY ")))
filter (("T7167". "SALESYEARMONTH" = 201505 AND SYS_OP_BLOOM_FILTER (: BF0000, "T7167" ".") SALESYEARMONTH', 'T7167 '. ((("" ANCESTOR_KEY ")))
70 - storage ((TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) > = 201505 AND "
TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) (< = 201505)) "
filter ((TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) > = 201505 AND "
TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) (< = 201505)) "
72 - access("L_OP".") OWNERID "=" L_US. " (' ' ID ')
73 - access("T765190".") WITH THE ID "=" L_OP. " ("' ACCOUNTID ')
77 - storage("T7167".") SALESYEARMONTH "= 201505)
filter ("T7167". ("SALESYEARMONTH" = 201505)
78 - storage("T7171".") SALES_YEAR_MONTH "= 201505)
filter ("T7171". ("SALES_YEAR_MONTH" = 201505)
81 - storage (SYS_OP_BLOOM_FILTER (: BF0000, "C0"))
filter (SYS_OP_BLOOM_FILTER (: BF0000, "C0"))
86 - storage ((TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) > = 201505 AND "
TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) (< = 201505)) "
filter ((TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) > = 201505 AND "
TO_NUMBER (TO_CHAR (INTERNAL_FUNCTION ("L_OP". "CLOSEDATE"), "YYYYMM")) (< = 201505)) "
88 - access("L_OP".") OWNERID "=" L_US. " (' ' ID ')
Note
-----
-dynamic sample used for this survey (level = 4)
-Automatic DOP: calculated degree of parallelism is 1 because of the parallel threshold
Although the table meet statistical why dynamic sampling is to be used? Why 15 million times ID 71, 72, 87 and 88 are executed, curious because that is where most of the time is spent. How can we reduce this 15 million probes?
Suggestions to reduce the response time sql would be useful.
Post edited by: Yasu masking of sensitive information (literal value)
YASU says:
For educational purposes could you please clarify why the optimizer has evaluated the join condition in the functioning of the FILTER to 15 million lines?
This is unusual, but TM_REP is attached to another PC_T_REP table using a join operation, so maybe it's the explanation of why it is moved to a FILTER operation had been delayed - could also be a side effect of the combination of ANSI join processing (Oracle internally transforms ANSI joins in Oracle join syntax) and the transformation of outer join internally.
Very curious to know how this is possible, could you please give us the hint/tour, you can use to push the inner join down execution plan is evaluated as soon as possible to reduce the data to be processed? I have a sql plus, where the situation is almost similar - ranks of filtering 2 million to the hash JOIN operation and return 0 rows. I can post the details of sql here but not to mix different sql question in the same post. Please let me know if you would like to give the details of this sql in this same thread, or a different thread? I searched for this type of information, but to no avail, so could you please suggest how this is possible, if not for this long sql then at least please provide a few examples/suggestions?
Normally you can influence this through the appropriate join order, for example with the help of the LEADING indicator, for filter indicator PUSH_SUBQ subqueries can also be useful for filtering at the beginning. But here the comment of Franck is particularly important - by leaning on the Cartesian join this problem here should be less relevant.
As I already said I would recommend here from scratch and think that all that this query is supposed to average and the question why most outer joins is actually converted into inner joins - the current query example returns the correct result?
Randolf
-
Misunderstanding of recursive subquery
Hello
To summarize our boredom, I have set up a test folder. Our data source are:
We want to join on column ELEMENT to generate recursivelyGRP ITEM ------------------ A F E F C G E G
An E (get by A-> F-> E F)
C E (get by C-> G-> G E)
A C (get by A-> C-> E E)
So, we write the following query:
but the C line is not generated :-(with datas as ( select 'A' as grp, 'F' as item from dual union all select 'E' as grp, 'F' as item from dual union all select 'C' as grp, 'G' as item from dual union all select 'E' as grp, 'G' as item from dual ) , RR(grp, item, lvl) as ( select grp, item, 0 from datas union all select o.grp , n.grp , lvl+1 from RR o , datas n where n.item = o.item and n.grp > o.grp ) select * from RR order by lvl
Can someone explain why recursion do not pass on the 1 iteration?
Kind regards.
Published by: user5774759 on October 1, 2012 00:44Hello
Maybe something like below.
I had to change the column names and aliases table because your were really confused me.[11.2] Scott @ My11g > !cat w.sql with datas(e1,e2) as ( select 'A' , 'F' from dual union all select 'E' , 'F' from dual union all select 'E' , 'G' from dual union all select 'C' , 'G' from dual ) ,rec(e1, e2, inv, lvl) as ( select e1, e2, cast(e1||e2 as varchar2(10)), 0 from datas union all select case when r.e1 in (a.e1,a.e2) then r.e2 else r.e1 end , case when a.e1 in (r.e1,r.e2) then a.e2 else a.e1 end , r.inv||case when a.e1 in (r.e1,r.e2) then a.e2 else a.e1 end , lvl+1 from rec r join datas a on ( ((a.e1=r.e1 or a.e1=r.e2) and instr(r.inv,a.e2)=0) or ((a.e2=r.e1 or a.e2=r.e2) and instr(r.inv,a.e1)=0) ) ) select distinct e1,e2,lvl from rec where e1
@w E1 E2 LVL ----- ----- ---------- A F 0 C G 0 E F 0 E G 0 A E 1 C E 1 F G 1 A G 2 C F 2 A C 3 10 rows selected. Elapsed: 00:00:00.04 -
subquery recursive datatypes of factoring?
Hi all
using 11.2.0.2.0
just mucking around with recursive subquery factoring, trying to get my head around it.
I can do this well:
but not with dates:SQL> with numlist (num) AS (SELECT 1 num 2 from dual 3 UNION ALL 4 SELECT numlist.num + 1 5 FROM numlist 6 where numlist.num < 10) 7 SELECT * 8 from numlist; NUM ---------- 1 2 3 4 5 6 7 8 9 10 10 rows selected.
I don't know what I have to do...SQL> WITH datelist (dte) AS (SELECT to_date('01-01-2011','dd-mm-yyyy') Dte 2 FROM dual 3 UNION ALL 4 SELECT datelist.dte + 1 5 FROM datelist 6 WHERE datelist.dte < trunc(SYSDATE)) 7 select * 8 from datelist; SELECT datelist.dte + 1 * ERROR at line 4: ORA-01790: expression must have same datatype as corresponding expression
I'm sure it's a pretty simpleHello
Don't try to understand this; There is a bug WITH recursive clauses and DATEs.
-
Can I use the Connect By operator to generate a set?
Connect By operator is a way to manage hierarchical models implemented through tables.
Is it possible to use generate games as in CTE (or of the recursive subquery factoring)?
Hello
user576036 wrote:
Sorry, I should have made myself clearer...
Connect By using hierarchical tables: we take such a table and find all the managers of a worker or all ordered sub of a Manager, etc..
The CTE has also the possibility to take a select degenerate double and create from it a set of all numbers up to...
My question is if there is a way to use the connection by to create a game of duel, or it is impossible, and it works with hierarchical tables?
It is obvious that the CTE can all Connect By possible.
but it is also true to the other side?
Another question - what year was published the first version of Oracle that supports CTES?
Thank you very much!
CONNECT BY a designed for contiguity-model trees, as you described. In my previous post, I said that this was an area where CONNECT BY might be better than a WITH recursive clause. If I gave the impression that CONNECT BY is not good for anything else, I apologize. It is very useful for other things and better than recursive WITH many clauses.
For example, CONNECT BY can be used to generate a 'meter' table, for example, to get a 10 ranks, contain integers from 1 to 10:
SELECT LEVEL AS n
OF the double
CONNECT BY LEVEL<=>=>
It's actally a common use of CONNECT BY, and it is very effective.
I don't think that CONNECT BY can do everything that can make a WITH recursive clause. Perhaps CONNECT BY as well as MODEL or some XML functions, can do that a WITH recursive clause can do, but it could be much more difficult and far less effective.
WITH the clauses were new in Oracle 9.1, released in 2001.
Recursif WITH clauses were new in Oracle 11.2, released in 2009.
I think it's interesteing CONNECT BY has been integrated into Oracle 2, released in 1979.
-
Difference between a CROSS JOIN and a Cartesian product of the noted comma?
Hello everyone,
Oracle version: Oracle Database 11 g Enterprise Edition Release 11.2.0.1.0 - 64 bit
OS: Linux Fedora Core 17 (x86_64)
I was practicing on recursive subquery factoring based on oracle examples available in the documentation
http://docs.Oracle.com/CD/E11882_01/server.112/e26088/statements_10002.htm#i2129904
I was working on an example that displays the hierarchy of each manager with related employees. Here's how
Which gives the desired resultWITH tmptab(empId, mgrId, lvl) AS ( SELECT employee_id, manager_id, 0 lvl FROM employees WHERE manager_id IS NULL UNION ALL SELECT employee_id, manager_id, lvl+1 FROM employees, tmptab WHERE (manager_id = empId) ) SEARCH DEPTH FIRST BY mgrId SET order1 SELECT LPAD(' ', lvl * 3, ' ') || empId AS empId FROM tmptab;
However, by chance, I noticed that if I put CROSS JOIN instead of put a comma between table names, the same query behaves differently.EMPID --------------------- 100 101 108 109 110 111 112 113 200 203 204 205 206 102 103 104 105 106 107 114 115 116 117 118 119 120 125 126 127 128 180 181 182 183 121 129 130 131 132 184 185 186 187 122 133 134 135 136 188 189 190 191 123 137 138 139 140 192 193 194 195 124 141 142 143 144 196 197 198 199 145 150 151 152 153 154 155 146 156 157 158 159 160 161 147 162 163 164 165 166 167 148 168 169 170 171 172 173 149 174 175 176 177 178 179 201 202 107 rows selected. SQL>
In other words, if instead of writing
I am writing. . . UNION ALL SELECT employee_id, manager_id, lvl+1 FROM employees, tmptab WHERE (manager_id = empId)
I get the following error message. . . UNION ALL SELECT employee_id, manager_id, lvl+1 FROM employees CROSS JOIN tmptab WHERE (manager_id = empId)
Any idea?ERROR at line 4: ORA-32044: cycle detected while executing recursive WITH query
Correct me if I'm wrong, but I remember, oracle supports as many JOIN CROSSROADS notation for Cartesian product (vector product =). For example
So if the two rated commas and CROSS JOIN have the same semantics, why do I get a cycle mentioned above cites recursive subquery factoring while the same query works pretty well with comma between table instead of CROSS JOIN names? Because if a cycle is detected (= current element ancestor) it means that the product with the CROSS JOIN notation produces duplicates which are absent in the result of the Cartesian product rated comma.SQL> WITH tmptab1 AS 2 ( 3 SELECT 'a1' AS colval FROM DUAL UNION ALL 4 SELECT 'a2' AS colval FROM DUAL UNION ALL 5 SELECT 'a3' AS colval FROM DUAL 6 ), 7 tmptab2 AS 8 ( 9 SELECT 'b1' AS colval FROM DUAL UNION ALL 10 SELECT 'b2' AS colval FROM DUAL 11 ) 12 SELECT t1.colval, t2.colval 13 FROM tmptab1 t1 CROSS JOIN tmptab2 t2; CO CO -- -- a1 b1 a2 b1 a3 b1 a1 b2 a2 b2 a3 b2 6 rows selected. SQL> LIST 13 13* FROM tmptab1 t1 CROSS JOIN tmptab2 t2 SQL> SQL> SQL> CHANGE /CROSS JOIN/, 13* FROM tmptab1 t1 , tmptab2 t2 SQL> SQL> SQL> LIST 1 WITH tmptab1 AS 2 ( 3 SELECT 'a1' AS colval FROM DUAL UNION ALL 4 SELECT 'a2' AS colval FROM DUAL UNION ALL 5 SELECT 'a3' AS colval FROM DUAL 6 ), 7 tmptab2 AS 8 ( 9 SELECT 'b1' AS colval FROM DUAL UNION ALL 10 SELECT 'b2' AS colval FROM DUAL 11 ) 12 SELECT t1.colval, t2.colval 13* FROM tmptab1 t1 , tmptab2 t2 SQL> SQL> / CO CO -- -- a1 b1 a2 b1 a3 b1 a1 b2 a2 b2 a3 b2 6 rows selected. SQL>
I would appreciate it if you could kindly shed some light.
Thanks in advance,
Kind regards
DariyooshHello
dariyoosh wrote:
... Oracle terminology could become really confusing. But once again, according to the online glossary, a Cartesian product is apparently regarded as a join
http://docs.Oracle.com/CD/E11882_01/server.112/e25789/glossary.htm?type=popup#CNCPT44493
>There is no doubt that a Cartesian product (also called cross join) is a join. If loops in a WITH recursive clause are detected after completing the joins, but before other conditions apply, the relevant question here is "what are the requirements to join?
In the ANSI syntax, the distinction is always clear. Join conditions occur in the... Clause WESELECT employee_id, manager_id, lvl + 1 FROM employees JOIN tmptab ON (manager_id = empId) -- Join condition ;
and other conditions occur in the WHERE (or HAVING or CONNECT BY) clause.
SELECT employee_id, manager_id, lvl + 1 FROM employees CROSS JOIN tmptab WHERE (manager_id = empId) -- NOT a join condition ;
In the joins of the former, it seems to be the case that any condition involving 2 or more tables (or the + indicator of outer join) is a condtion of join:
SELECT employee_id, manager_id, lvl + 1 FROM employees , tmptab WHERE (manager_id = empId) -- Join condition ;
Maybe you are looking for
-
I am referring to the question posed by Firefox ' "do you want Firefox to remember the password for _ on mozilla.com?".Option are to remember, never for this site, not now. My daughter accidentally clicked remember for his gmail account and we would
-
El Capitan is safe for my Macbook Pro?
Hi friends, I need advice. Update of Safari and downloads of some products to my MacBook Pro, I need to upgrade my operating system Mac OS X Lion 10.7.5, 8 GB 1333 MHz DDR3, Intel Core i5 2.4 GHz processor memory and El Capitan is the latest update a
-
Pavilion a4316f: recovery disk failure
My pc has a new hard drive and the motherboard. I ordered and paid for the cd of recovery for this on the site. The recovery software GET were he wants you start after backup or begin without saving. He ten request the recovery 1 disc that sits in
-
What is a typical level of noise on a signal 4-20 my?
I have a laser distance measuring device "time of flight" connected to a NI9203 module (I +/-20mA). The sensor is configured to my exit 4 at 200 mm and 20 my 1800 mm (i.e. 0.01 my / mm). The application requires a resolution of 1 mm, but I am curren
-
No noise even after replacing the speakers
Original title : NO VOLUME... HI, I LOST THE SPEAKER VOLUME I REPLACED WITH NEW SPEAKERS STILL NO VOLUME, I'VE DONE EVERYTHING IN THE CONTROL PANEL DON'T ALWAYS NOT VOLUME. CAN SOMEONE PLEASE GIVE ME SOME INFO... Thank you.