Depth first in hierarchical query
Does anybody know how to make a depth first run through of a
hierarchical query using START WITH ... CONNECT BY PRIOR???
Allright, here comes the details:
Imagine that you need to perform a depth first run of a table
that looks like this:
id
parent_id
priority
depth
attribute1
attribute2
id is primary key and parent_id foreign key to id, i.e. it
references id. The priority is forth numbered from 1 to n if n
children are attached to the same parent. The depth indicates
the depth in the tree the row is. Example rows:
1 null 1 0 foo bar ...
2 1 2 1 foobar barfoo ...
3 1 1 1 barbar foofoo ...
4 null 2 0 foo bar ...
5 2 1 2 foofoobar barfoofoo ...
6 2 3 2 foobarfoo barfoobar ...
7 2 2 2 foofoofoo barbarbar ...
8 6 1 3 foooooooooo baaaaaaaaar ...
9 1 3 1 fooooo baaaar ...
The desired result should then be (assume that all attributes
are selected):
1 null 1 0 foo bar ...
3 1 1 1 barbar foofoo ...
2 1 2 1 foobar barfoo ...
5 2 1 2 foofoobar barfoofoo ...
7 2 2 2 foofoofoo barbarbar ...
6 2 3 2 foobarfoo barfoobar ...
8 6 1 3 foooooooooo baaaaaaaaar ...
9 1 3 1 fooooo baaaar ...
4 null 2 0 foo bar ...
My attempt was to try something like:
SELECT id, parent_id, priority, attribute1, attribute2, ...
FROM table
CONNECT BY PRIOR id = parent_id START WITH id = ?
ORDER BY depth, priority
I know that the depth can be obtained from CONNECT BY PRIOR, but
I use the depth in other SQLs, so just assumes that you have
it...
This SELECT ofcause only selects from a given id and down, but
that is also ok; we can just start with id = 1. And the SELECT
needs to be given the root id, since that is the way the
application works...
But this does not work, since it groups by depth thus return all
children (c1...cN) at depth i for parent_id x before the
children of a child in (c1...cN) at depth i+1.
So, I guess the question is... If the above SELECT can be used
showhow, then
SELECT id, parent_id, priority, attribute1, attribute2, ...
FROM table
CONNECT BY PRIOR id = parent_id START WITH id = ?
ORDER BY __WHAT_GOES_HERE___, priority
or if not, please state a SELECT statement that does the trick!
Regards
Sxren
Similar Messages
-
Problem with different execution paths in hierarchical query
Hello,
I have problems with the following query:
SELECT DISTINCT P.ID FROM PRODUCTELEMENTIMPL P WHERE ( ( LABEL = 'SomeLabel' AND PRODUCTELEMENTTYPE = 'SomeText' AND ( STATE = 'created' OR STATE = 'stored' OR STATE = 'archived' OR STATE = 'archivedRestored' ) ) ) START WITH P.ID = 42 CONNECT BY PRIOR P.ID = P.PARENT
We have two databases (an Oracle 10g XE and Oracle10g Enterprise). In the XE Database the query is executed very fast, but in the main installation it takes minutes. If I "explain" the query I get two different execution paths:
The fast:
ID PARENT_ID LEVEL SQL Kosten Anzahl Zeilen
0 - 1 SELECT STATEMENT 20 49
1 0 2 HASH UNIQUE 20 49
2 1 3 FILTER - -
3 2 4 CONNECT BY WITH FILTERING - -
4 3 5 TABLE ACCESS BY INDEX ROWID PRODUCTELEMENTIMPL (TABLE) - -
5 4 6 INDEX UNIQUE SCAN SYS_C0072201 (INDEX (UNIQUE)) 2 1
6 3 5 NESTED LOOPS - -
7 6 6 BUFFER SORT - -
8 7 7 CONNECT BY PUMP - -
9 6 6 TABLE ACCESS BY INDEX ROWID PRODUCTELEMENTIMPL (TABLE) 19 49
10 9 7 INDEX RANGE SCAN PRODUCTELEMENTIMPL_IDX1 (INDEX) 3 49
11 3 5 TABLE ACCESS FULL PRODUCTELEMENTIMPL (TABLE) 19 49
Slow:
ID PARENT_ID LEVEL SQL Kosten Anzahl Zeilen
0 1 SELECT STATEMENT 1 1
1 0 2 HASH UNIQUE 1 1
2 1 3 FILTER
3 2 4 CONNECT BY WITHOUT FILTERING
4 3 5 TABLE ACCESS BY INDEX ROW 3 1
ID PRODUCTELEMENTIMPL (TABLE)
5 4 6 INDEX UNIQUE SCAN SYS_C0 2 1
020528 (INDEX (UNIQUE))
6 3 5 TABLE ACCESS FULL PRODUCT 6628 1100613
ELEMENTIMPL (TABLE)
Any ideas how to avoid this full table scan?
bye
Roland SpatzeneggerHello,
thank you for your replies. The indices and table schemas are the "same", but only the content for the tables was mirrored.
We made some tests with dropping and/or analyzing the tables, but it didn't change anything.
The main problem is that the query takes 33s in the productive environment for searching in a couple of rows. At the moment it's faster to make
SELECT DISTINCT P.ID, P.STATE FROM PRODUCTELEMENTIMPL P WHERE ( ( LABEL = 'SomeLabel' AND PRODUCTELEMENTTYPE = 'SomeText' ) ) START WITH P.ID = 42 CONNECT BY PRIOR P.ID = P.PARENT
and to test in the application if the state-values match ;-)
If I add the hint /*+ no_filtering */ in the test environment, I get the same "slow" execution path as in the production environment. So the question is, what prevents the filtering in "connect by"?
(I think in the fast version it filters only the results of the hierarchical query, in the slow version it first filters the whole table and joins/merge it with the hierachical result).
bye
Roland Spatzenegger -
Hierarchical Query Duplication Issue
Hi All,
I am trying to create a tree structure for a "NOT SO" elegantly structured data(for tree type traversing). The below mentioned query is the sample of the data that I have in the real-time system.
The assumption & requirements to be considered are as follows:
1. The query with the rep data(i.e. first WITH clause query with 9 rows) is the master data that needs to be shown in hierarchical structure.
2. The query with the group data is joined with the rep data on GROUP_ID to get the tree structure be traversing on group_id and PARENT_GROUP_ID(i.e. Second WITH clause query)
The problem is I am getting 16 rows instead of 9(which are expected since the master rep data query has 9 rows). Some part of the Tress is getting wrongly duplicated.
Can anybody please point to me where I am making any mistake in the way this hierarchical query is written.
SELECT
REP_EMAIL
,REP_TYPE
,GROUP_MGR_EMAIL
,GROUP_ID
,PARENT_GROUP_ID
,RPAD('*',LEVEL*10,'*')||REP_EMAIL REP_EMAIL
-- ,RPAD('*',LEVEL*10,'*')||GROUP_MGR_EMAIL GROUP_MGR_EMAIL
,SYS_CONNECT_BY_PATH(REP_EMAIL, '/') "Path"
FROM (
SELECT * FROM (
WITH REP AS(
SELECT '[email protected]' AS EMAIL, 'REP' AS REP_TYPE, 112 AS GROUP_ID, 112 AS PARENT_GROUP_ID FROM DUAL UNION
SELECT '[email protected]', 'REP' , 112 , 112 FROM DUAL UNION
SELECT '[email protected]', 'REP' , 115 , 115 FROM DUAL UNION
SELECT '[email protected]', 'REP' , 115 , 115 FROM DUAL UNION
SELECT '[email protected]', 'MGR' , 112 , 117 FROM DUAL UNION
SELECT '[email protected]', 'MGR' , 115 , 119 FROM DUAL UNION
SELECT '[email protected]', 'MGR' , 117 , 2 FROM DUAL UNION
SELECT '[email protected]', 'MGR' , 119 , 2 FROM DUAL UNION
SELECT '[email protected]', 'REP' , 115 , 115 FROM DUAL
SELECT EMAIL AS REP_EMAIL, REP_TYPE, GROUP_ID AS REP_GROUP_ID, PARENT_GROUP_ID AS REP_PARENT_GROUP_ID
FROM REP) REP
JOIN (
SELECT * FROM (
WITH GRP AS (
SELECT 1 AS GROUP_ID, NULL AS PARENT_GROUP_ID, '[email protected]' AS GROUP_MGR_EMAIL FROM DUAL UNION
SELECT 2 , 1 , '[email protected]' FROM DUAL UNION
SELECT 50 , 2 , '[email protected]' FROM DUAL UNION
SELECT 112 , 117 , '[email protected]' FROM DUAL UNION
SELECT 115 , 119 , '[email protected]' FROM DUAL UNION
SELECT 117 , 2 , '[email protected]' FROM DUAL UNION
SELECT 119 , 2 , '[email protected]' FROM DUAL
SELECT GROUP_ID, PARENT_GROUP_ID, GROUP_MGR_EMAIL
FROM GRP) GRP) GRP
ON (REP.REP_PARENT_GROUP_ID = GRP.GROUP_ID))
START WITH PARENT_GROUP_ID = 1
CONNECT BY PARENT_GROUP_ID = PRIOR GROUP_IDAny help would be really appreciated.
Thank you,
Warm Regards
GoldiGoldi wrote:
The problem is I am getting 16 rows instead of 9(which are expected since the master rep data query has 9 rows). Some part of the Tress is getting wrongly duplicated. I don't think it is getting wrongly duplicated...
SQL> ed
Wrote file afiedt.buf
1 WITH REP AS (SELECT EMAIL AS REP_EMAIL, REP_TYPE, GROUP_ID AS REP_GROUP_ID, PARENT_GROUP_ID AS REP_PARENT_GROUP_ID
2 FROM (
3 SELECT '[email protected]' AS EMAIL, 'REP' AS REP_TYPE, 112 AS GROUP_ID, 112 AS PARENT_GROUP_ID FROM DUAL UNION
4 SELECT '[email protected]' , 'REP' , 112 , 112 FROM DUAL UNION
5 SELECT '[email protected]' , 'REP' , 115 , 115 FROM DUAL UNION
6 SELECT '[email protected]' , 'REP' , 115 , 115 FROM DUAL UNION
7 SELECT '[email protected]' , 'MGR' , 112 , 117 FROM DUAL UNION
8 SELECT '[email protected]' , 'MGR' , 115 , 119 FROM DUAL UNION
9 SELECT '[email protected]' , 'MGR' , 117 , 2 FROM DUAL UNION
10 SELECT '[email protected]' , 'MGR' , 119 , 2 FROM DUAL UNION
11 SELECT '[email protected]' , 'REP' , 115 , 115 FROM DUAL
12 )
13 )
14 ,GRP AS (
15 SELECT 1 AS GROUP_ID, NULL AS PARENT_GROUP_ID, '[email protected]' AS GROUP_MGR_EMAIL FROM DUAL UNION
16 SELECT 2 , 1 , '[email protected]' FROM DUAL UNION
17 SELECT 50 , 2 , '[email protected]' FROM DUAL UNION
18 SELECT 112 , 117 , '[email protected]' FROM DUAL UNION
19 SELECT 115 , 119 , '[email protected]' FROM DUAL UNION
20 SELECT 117 , 2 , '[email protected]' FROM DUAL UNION
21 SELECT 119 , 2 , '[email protected]' FROM DUAL
22 )
23 --
24 SELECT REP_EMAIL
25 ,REP_TYPE
26 ,GROUP_MGR_EMAIL
27 ,GROUP_ID
28 ,PARENT_GROUP_ID
29 -- ,RPAD('*',LEVEL*10,'*')||REP_EMAIL REP_EMAIL
30 -- ,RPAD('*',LEVEL*10,'*')||GROUP_MGR_EMAIL GROUP_MGR_EMAIL
31 -- ,SYS_CONNECT_BY_PATH(REP_EMAIL, '/') "Path"
32 FROM REP JOIN GRP ON (REP.REP_PARENT_GROUP_ID = GRP.GROUP_ID)
33 --CONNECT BY PARENT_GROUP_ID = PRIOR GROUP_ID
34* --START WITH PARENT_GROUP_ID = 1
SQL> /
REP_EMAIL REP GROUP_MGR_EMAIL GROUP_ID PARENT_GROUP_ID
[email protected] REP [email protected] 112 117
[email protected] REP [email protected] 115 119
[email protected] REP [email protected] 115 119
[email protected] REP [email protected] 112 117
[email protected] REP [email protected] 115 119
[email protected] MGR [email protected] 119 2
[email protected] MGR [email protected] 2 1
[email protected] MGR [email protected] 2 1
[email protected] MGR [email protected] 117 2
9 rows selected.There are multiple matches in REP for the parent group id's. e.g. xyz2@.. and xyz3@.. both have a parent of 2 so you'll get duplicated branches from that as the connect by is going on the group id's e.g.
1
2
117
112
112
119
115
115
115
2
117
112
112
119
115
115
115The duplicates are caused by the rows in REP. So Oracle is doing what you are asking of it because there is nothing further to restrict the connection to make one branch of 2 unique from the other branch of 2 -
Hi
Question:
In a hierarchical query, is it possible for a row to have more than one immediate ancestor?
Answer:
No
No? Surely, it's yes?
Thanks,
JasonAs Frank pointed out already hierarhical most often means a tree (data structure) to deal with.
There must usually be just one boss (the root) in which case the answer is no.
Something to read: http://en.wikipedia.org/wiki/Tree_(data_structure)
You can find out Solomon spoke about a generalization therein.
Related to forum troubles:
If I login first thing after reaching forum, the behaviour is rather consistent - I'm allowed to post answers, otherwise ...
Regards
Etbin -
Problems with Views based on a Hierarchical Query
Datamodeler 3.1.3.706 (SQL Dev 3.2.10.09):
When creating a view that utilizes a Hierarchical Query, the Query Builder encounters various difficulties:
When pasting in SQL code, if the view is saved without first clicking the update diagram button, the object in the view entity relationship diagram provides a faithful representation of the view without errors, but when reopening the view, the code is missing.
Simple Example using the classic emp table:
SELECT level lev
, emp.*
FROM emp
CONNECT BY prior empno = mgr
START WITH mgr IS NULLIf the update diagram button is pushed to refresh the graphical view. It mangles the connect by clause and the view gets marked with a warning/error icon in the relationship diagram, but the now mangled code remains available on reopening the query builder.
Same code as above after clicking the Update Diagram button:
SELECT Level lev
, emp.*
FROM emp
CONNECT BYFurther issues are encountered if the query contains any of the CONNECT_BY_% hierarchical pseudo columns:
SELECT level
, emp.*
, connect_by_root emp.ename root_ename
FROM emp
CONNECT BY prior empno = mgr
START WITH mgr IS NULL;In this case pasting in the code and clicking either the Update Diagram button or the OK button results in an "Unexpected Token" parsing error.
These issues are encountered with both the Logical and Relational models.
Is this a known issue? I've searched this forum but haven't found any references to it.
Thanks,
SentinelHi Sentinel,
I logged a bug for that.
You can try DM 3.3 it deals better with first problem, parsing of connect_by_root operator will pass if you don't use alias.
Philip -
Hi all,
I must be tired and cannot think clearly, so I'm a bit confused the following query.
The environment is still Oracle 9i:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
PL/SQL Release 9.2.0.8.0 - Production
CORE 9.2.0.8.0 Production
TNS for HPUX: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production
Suppose that I have the following data:
with mydata as
select 1 code, null code_high, 'John' cname, 'Smith' csurname, 'X' resp from dual union all
select 2 code, 1 code_high, 'Bill' cname, 'White' csurname, null resp from dual union all
select 3 code, 2 code_high, 'Fred' cname, 'Reed' csurname, 'X' resp from dual union all
select 4 code, null code_high, 'Tim' cname, 'Hackman' csurname, 'X' resp from dual union all
select 5 code, 4 code_high, 'John' cname, 'Reed' csurname, null resp from dual union all
select 6 code, 5 code_high, 'Bill' cname, 'Hakcman' csurname, 'X' resp from dual union all
select 7 code, 6 code_high, 'Fred' cname, 'White' csurname, null resp from dual union all
select 8 code, 7 code_high, 'Bill' cname, 'Smith' csurname, null resp from dual union all
select 9 code, 8 code_high, 'Tom' cname, 'Reed' csurname, null resp from dual
select *
from mydata;
CODE CODE_HIGH CNAME CSURNAME RESP
1 John Smith X
2 1 Bill White
3 2 Fred Reed X
4 Tim Hackman X
5 4 John Reed
6 5 Bill Hakcman X
7 6 Fred White
8 7 Bill Smith
9 8 Tom Reed
This is a hierarchical query where code_high represent the father.
I need to find in the hierarchy the upper responsible level for each code.
Suppose that I want to find in the hierarchy the first one having resp='X'.
Running the following query I can find it for code = 9
select code, cname, csurname
from mydata
where resp = 'X'
and rownum = 1
connect by prior code_high = code
start with code = 9;
CODE CNAME CSURNAME
6 Bill Hakcman
Is there a way to get the whole list with the corresponding responsible.
Here is the expected output:
CODE CODE_HIGH CNAME CSURNAME RESP RESP_CODE RESP_NAME RESP_SURNAME
1 John Smith X 1 John Smith
2 1 Bill White 1 John Smith
3 2 Fred Reed X 3 Fred Reed
4 Tim Hackman X 4 Tim Hackman
5 4 John Smith 4 Tim Hackman
6 5 Bill Hakcman X 6 Bill Hakcman
7 6 Fred White 6 Bill Hakcman
8 7 Bill Smith 6 Bill Hakcman
9 8 Tom Reed 6 Bill Hakcman
Regards.
AlbertoHi Anar,
check my post and my expected output.
This is too simple and it is not what I need.
Your code is showing this output:
SS CODE CNAME CSURNAME RESP
1 1 John Smith X
1 3 Fred Reed X
1 4 Tim Hackman X
1 6 Bill Hakcman X
Actually the only way I have found (in Oracle 9i) is the following:
select code, code_high, cname, csurname, resp
, ( select code
from mydata
where resp='X'
and rownum=1
connect by prior code_high = code
start with code=a.code
) resp_code
, ( select cname
from mydata
where resp='X'
and rownum=1
connect by prior code_high = code
start with code=a.code
) resp_name
, ( select csurname
from mydata
where resp='X'
and rownum=1
connect by prior code_high = code
start with code=a.code
) resp_surname
from mydata a;
CODE CODE_HIGH CNAME CSURNAME RESP RESP_CODE RESP_NAME RESP_SURNAME
1 John Smith X 1 John Smith
2 1 Bill White 1 John Smith
3 2 Fred Reed X 3 Fred Reed
4 Tim Hackman X 4 Tim Hackman
5 4 John Reed 4 Tim Hackman
6 5 Bill Hakcman X 6 Bill Hakcman
7 6 Fred White 6 Bill Hakcman
8 7 Bill Smith 6 Bill Hakcman
9 8 Tom Reed 6 Bill Hakcman
But I don't like this.
Regards.
Alberto -
CONTAINS in hierarchical query
Hello friends!
I have a table that describes some tree:
CATEGORIES (cat_id NUMBER, parent_id NUMBER, title VARCHAR2,
description VARCHAR2);
The following query works fast:
SELECT count(*)
FROM categories
WHERE CONTAINS( title,'Moscow WITHIN description OR Moscow
WITHIN title', 1 ) > 0;
But the hierarchical query
SELECT count(*)
FROM categories
WHERE CONTAINS( title, 'Moscow WITHIN description OR Moscow
WITHIN title', 1 ) > 0
START WITH cat_id = 1 CONNECT BY PRIOR cat_id = parent_id;
works very slowly.
What’s wrong and what should I do?
Thank you!
Index is:
begin
ctx_ddl.create_preference('cat_lexer', 'BASIC_LEXER');
ctx_ddl.set_attribute ('cat_lexer', 'printjoins', '_-');
ctx_ddl.set_attribute ('cat_lexer', 'index_themes', 'NO');
ctx_ddl.set_attribute ('cat_lexer', 'index_text', 'YES');
end;
exec ctx_cd.Create_CDstore('categories_cdstore', 'categories')
exec ctx_cd.Add_Column ('categories_cdstore', 'title')
exec ctx_cd.Add_Column ('categories_cdstore', 'description')
create index categ_title_index on categories( title ) INDEXTYPE
IS ctxsys.context
PARAMETERS ('LEXER cat_lexer DATASTORE categories_cdstore
SECTION GROUP categories_cdstore MEMORY 50M');Thank you Thomas,
I tried to use subquery like this:
SELECT count(*)
FROM (SELECT cat_id, title, description
FROM categories
START WITH cat_id = 2 CONNECT BY PRIOR cat_id =
parent_id) c
WHERE CONTAINS( c.title,'Moscow WITHIN description OR Moscow
WITHIN title', 1 ) > 0;
It works more faster <0.5-1 min.> then that in my first post <5-
7 min.>, but still slow than I wish.
If I use normal index (WHERE title LIKE '%Moscow%' AND ...) the
answer is immediate in this query!!! Yo!
Is this an Oracle's bag or mine?
Indeed, I try to solve more complex task.
I have another table RESOURCES (cat_id, url, title) that is
detail of CATEGORIES table. Assosiation one-to-many
categories.cat_id = resources.cat_id.
SELECT COUNT(*)
FROM resources r, (
SELECT cat_id
FROM categories
START WITH cat_id = 2 CONNECT BY PRIOR cat_id =
parent_id) c
WHERE c.cat_id = r.cat_id
AND CONTAINS(title,'Moscow',2)>0;
Again this works more slowly than if I use NORMAL index. -
ORACLE 9I의 HIERARCHICAL QUERY의 ORDER SIBLINGS BY CLAUSE
제품 : ORACLE SERVER
작성날짜 : 2003-10-22
(V9I) Oracle 9i의 Hierarchical query의 ORDER SIBLINGS BY CLAUSE
===============================================================
PURPOSE
이 문서는 Oracle 9i의 new feature인 ORDER SIBLINGS BY 절을
Hierarchical query에 사용하는 예를 통하여 특정 컬럼을 기준으로
Ordering된 형태로 display하는 방법을 보여준다.
Explanation & Example
Hierarchical query를 구현할 때 ORDER BY 절을 사용하는 것은
Oracle 7.1 버젼부터 가능한 것이었다.
그러나, 순서대로 ordering되지 않고 특정 컬럼(emp table의 ename)을
기준으로 ordering하기를 원한다면 <Bulletin:10373>처럼 procedure를
작성하여야만 하였다.
그러나, Oracle 9i 에서는 ORDER BY 절 대신에 ORDER SIBLINGS BY 절을
사용할 수 있어 user-defined stored procedure를 만들 필요가 없게 되었다.
1) Ordering 하기 전의 emp table의 Hierarchical query
SQL> @a
ename EMPNO MGR JOB
KING 7839 PRESIDENT
JONES 7566 7839 MANAGER
SCOTT 7788 7566 ANALYST
ADAMS 7876 7788 CLERK
FORD 7902 7566 ANALYST
SMITH 7369 7902 CLERK
BLAKE 7698 7839 MANAGER
ALLEN 7499 7698 SALESMAN
WARD 7521 7698 SALESMAN
MARTIN 7654 7698 SALESMAN
TURNER 7844 7698 SALESMAN
ename EMPNO MGR JOB
JAMES 7900 7698 CLERK
CLARK 7782 7839 MANAGER
MILLER 7934 7782 CLERK
14 rows selected.
Ordering 하기 전의 a.sql 은 다음과 같다.
col ename format a25
col empno format 99999
col mgr format 99999
col job format a15
select rpad(' ', LEVEL*5) || ename "ename", empno, mgr, job
from emp
start with job='PRESIDENT'
connect by prior empno=mgr;
2) 9i의 new feature인 Hierarchical query를 사용하여 Ordering한 경우
SQL> @new_a
ename EMPNO MGR JOB
KING 7839 PRESIDENT
BLAKE 7698 7839 MANAGER
ALLEN 7499 7698 SALESMAN
JAMES 7900 7698 CLERK
MARTIN 7654 7698 SALESMAN
TURNER 7844 7698 SALESMAN
WARD 7521 7698 SALESMAN
CLARK 7782 7839 MANAGER
MILLER 7934 7782 CLERK
JONES 7566 7839 MANAGER
FORD 7902 7566 ANALYST
ename EMPNO MGR JOB
SMITH 7369 7902 CLERK
SCOTT 7788 7566 ANALYST
ADAMS 7876 7788 CLERK
14 rows selected.
Ordering하기 위해 사용한 new_a.sql 은 다음과 같다.
col ename format a25
col empno format 99999
col mgr format 99999
col job format a15
select rpad(' ', LEVEL*5) || ename "ename", empno, mgr, job
from emp
start with job='PRESIDENT'
connect by prior empno=mgr
order siblings by ename;
Reference Documents
<Bulletin:10373>Thanks to Kendenny, Boneist and Odie.
Got the point that "Order Siblings by clause" cannot be used with connect by query with analytical function, Thanks Kendenny.
Yes, I now use main query and subquery, however the subquery be just "connect by" and have the all html tags added in the main query.
The below query is working now.
SELECT
CASE WHEN LAG(mylevel,1,0) OVER (ORDER BY myrownum) >= mylevel THEN '<li>'
ELSE
CASE LEAD(mylevel) OVER (ORDER BY myrownum)
WHEN mylevel THEN
CASE WHEN myrownum = 1 THEN '<ul id="sidebarmenu1" '
ELSE '<ul'
END ||'><li>'
ELSE
CASE WHEN myrownum =1 THEN '<ul id="sidebarmenu1"'
ELSE '<ul '
END ||' ><li>'
END
END ||'<a href="'||
CASE WHEN link_url IS NOT NULL THEN
link_url||'title="'||menu_item||'"'
ELSE '#"' END ||
'><span>'||short_menu_item||'</span></a>'||
CASE mylevel - LEAD(mylevel,1,1) OVER (ORDER BY myrownum)
WHEN -1 THEN NULL
WHEN 0 THEN '</li>'
ELSE REPLACE(LPAD('*', myleveL-LEAD(mylevel,1,1) OVER (ORDER BY myrownum),'*'), '*','</li></ul></li>')
END ||
CASE WHEN LEAD(mylevel,1,0) OVER (ORDER BY myrownum) = 0 THEN '</ul>'
ELSE NULL END unordered_List,
menu_item, menu_id,
above_menu_id
FROM (
SELECT LEVEL mylevel, ROWNUM myrownum,daevmt.*
FROM dae_vs_my_tasks daevmt
CONNECT BY PRIOR daevmt.menu_id = daevmt.above_menu_id
START WITH daevmt.above_menu_id = 'TOPMENU'
ORDER SIBLINGS BY display_order
) t;
Odie, I tried altering the session for the flag, still the first query was not working.
Thanks again all for your great time in answering me. -
Hi,
I have a hierarchical query which takes 2 seconds to execute. I need to get this down to milli seconds.
The table has around 8000 records. The query will never return more than 20 or so records. There is only ever 2 levels to the query.
I am quite surprised at this because it is a very simple query no table joins etc and I would have though 8000 records was nothing for Oracle.
Select id, parent_id, col1, col2, col3, col4, col5, col6
from my_table
where id=500
start with parent_id is null
connect by prior id = parent_id;
I have even tried initializing the start with say with 0 and making it a not null column...... indexing the columns used in the start with + connect by
I have tried various indexing stratergies. Does anyone have any similar experience? I am using Oracle 9i.
Thanks in advanceHow can I utilise the above query in a view if at all? Will I be able to pass in differnt ID's to the START WITH...?Certainly, you can. For example, you can use packaged
public variable to pass a parameter or Oracle CONTEXT:
SQL> create or replace package pass_param is
2 empno emp.empno%TYPE;
3 function get_empno return emp.empno%TYPE;
4 end;
5 /
 
Package created.
 
SQL> create or replace package body pass_param is
2 function get_empno return emp.empno%TYPE
3 is
4 begin
5 return empno;
6 end;
7 end;
8 /
 
Package body created.
 
SQL> create or replace view emp_v as
2 select ename from emp
3 start with empno = pass_param.get_empno
4 connect by prior empno = mgr
5 /
 
View created.
 
SQL> exec pass_param.empno := 7839;
 
PL/SQL procedure successfully completed.
 
SQL> select * from emp_v;
 
ENAME
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER
 
14 rows selected.
 
SQL> exec pass_param.empno := 7698;
 
PL/SQL procedure successfully completed.
 
SQL> select * from emp_v;
 
ENAME
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
 
6 rows selected. or:
SQL> create or replace package set_param
2 is
3 procedure set_empno(empno in number);
4 end;
5 /
 
Package created.
 
SQL> create or replace package body set_param
2 is
3 procedure set_empno(empno in number)
4 is
5 begin
6 dbms_session.set_context('empnamespace','empno',empno);
7 end;
8 end;
9 /
 
Package body created.
 
SQL> create or replace context empnamespace using set_param;
 
Context created.
 
SQL> create or replace view emp_v as
2 select ename from emp
3 start with empno = sys_context('empnamespace','empno')
4 connect by prior empno = mgr
5 /
 
View created.
 
SQL> exec set_param.set_empno(7698);
 
PL/SQL procedure successfully completed.
 
SQL> select * from emp_v;
 
ENAME
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
 
6 rows selected.
 
SQL> exec set_param.set_empno(7839);
 
PL/SQL procedure successfully completed.
 
SQL> select * from emp_v;
 
ENAME
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER
 
14 rows selected.Rgds. -
Too many results in hierarchically query
Hello all,
I'm searching for an idea to stop getting results 2, 3 and more times out of the following query
select
t.lvl,
t.syswflvl,
t.upper,
LPAD(' ', (lvl)*8)||t.code code,
LPAD(' ', (lvl)*8)||t.bezeichnung bezeichnung,
t.chk,
t.rang
from (
select '0' lvl, '0-'||to_char(syswftable,'0000000') syswflvl, '0- 0000000' upper, syscode code, bezeichnung, '' chk, 0 rang from wftable where (select count(wfm.syswftable) from wfm where wfm.syswftable = wftable.syswftable) > 0 union
select '1' lvl, '1-'||to_char(syswfm,'0000000') syswflvl, '0-'||to_char(syswftable,'0000000') upper, syscode code, kurzbez bezeichnung, anzeigefilter chk, 1 rang from wfm union
select '2' lvl, '2-'||to_char(syswfa,'0000000') syswflvl, '1-'||to_char(syswfm,'0000000') upper, syscode code, kurzbez bezeichnung, bedingung chk, rang from wfa union
select '3' lvl, '3-'||to_char(syswfc,'0000000') syswflvl, '2-'||to_char(syswfa,'0000000') upper, syscode code, kurzbez bezeichnung, bedingung chk, rang from wfc union
select '4' lvl, '4-'||to_char(syswfg,'0000000') syswflvl, '3-'||to_char(syswfc,'0000000') upper, syscode code, kurzbez bezeichnung, bedingung chk, rang from wfg
) t
where ((t.chk not like '%and 0%'
and trim(t.chk) not like '0%')
or t.chk is null)
and upper not like '%-'
connect by nocycle prior syswflvl = upper
order siblings by upper, syswflvl, rang
What happens is, that I get the results from level 0 one times, from level 1 two times, from level 2 three times etc.
What I'm try to achive is to get only the whole thing once.
Hope you can see what my problem is ;-)
Regards
CarstenThe effect of not having a start with clause in a hierarchical query is that a hierarchy is produced starting at every possible entry-point. So, you'll get the hierachy from node 1, the hierarchy from all nodes 2, the hierarchy from all nodes 3 and so one. Whether it starts with the correct one or not is not really relevant, as you already figured out that you get too much....
So, just believe it, add a start with clause...and your problems are gone. -
Value of the start in the Select with in a Hierarchical Query
Exist any way for put in the select the value of the start with in a Hierarchical Query?
An example:
I'll need sth like
CTH@> select n code, level, np code_parent, 1 code_first_parent
2 from demo
3 start with n=1
4 connect by np = prior n
5 ;
CODE LEVEL CODE_PARENT CODE_FIRST_PARENT
1 1 1
2 2 1 1
3 3 2 1
4 4 3 1
5 5 4 1
6 6 5 1
7 7 6 1
8 8 7 1
9 9 8 1
10 10 9 1
-- Naturally it couldn´t be a constant value
The query
select n,d, level nivel
, np, prior n
from demo
start with n=1
connect by np = prior n
--Table and inserts
create table demo
( n number,
d varchar2(5),
np number);
insert into demo values (1,'A', null);
insert into demo values (2,'B',1);
insert into demo values (3,'C',2);
insert into demo values (4,'D',3);
insert into demo values (5,'E',4);
insert into demo values (6,'F',5);
insert into demo values (7,'G',6);
insert into demo values (8,'H',7);
insert into demo values (9,'I',8);
insert into demo values (10,'J',9);
insert into demo values (11,'K', null);
insert into demo values (12,'L',11);
insert into demo values (13,'M',12);
insert into demo values (14,'N',13);
insert into demo values (15,'O',14);
insert into demo values (16,'P',15);
Message was edited by:
cthOn 10g
connect_by_root(n)Best regards
Maxim -
[Oracle 8i] Need help pruning branches from a hierarchical query
My problem is that my hierarchical query seems only to trim out the values that don't meet my criteria, but still includes their children. When my query hits a record that does not meet my criteria, I want it to stop there. I've tried including the criteria in just the 'where' clause of the query, and have also put the criteria in the 'connect by' clause as well, but nothing has fixed it. Please keep in mind I'm using Oracle 8i, so I can't use some of the 'nicer' statements for hierarchical queries that they introduced in 9. I'm stuck with 'Start With...Connect By'.
I have sample tables/data that I can post if someone needs to see that to help me, but to start with, here's my current query:
SELECT *
FROM (
SELECT
LEVEL
, c_bill.comp_part_nbr AS c_part_nbr
, (select c_part.part_desc
FROM part c_part
WHERE c_part.part_nbr=c_bill.comp_part_nbr) AS c_part_desc
, (SELECT c_part.part_type
FROM part c_part
WHERE c_part.part_nbr=c_bill.comp_part_nbr) AS c_part_type
, c_bill.qty_per AS c_qty_per_p
, c_bill.qty_per_type AS c_qty_per_type
, (SELECT c_part.qty_on_hand
FROM part c_part
WHERE c_part.part_nbr=c_bill.comp_part_nbr) AS c_qty_on_hand
, c_bill.oper_nbr AS rqd_at_op
, c_bill.comp_off_adj AS rqd_offset
, c_bill.bom_doc_nbr AS p_part_nbr
, (SELECT p_part.qty_on_hand
FROM part p_part
WHERE p_part.part_nbr=c_bill.bom_doc_nbr) AS p_qty_on_hand
FROM
BILL c_bill
WHERE
(c_bill.status = 'RL')
AND (c_bill.view_code IN ('M','G'))
AND (c_bill.end_eff_dt > SYSDATE)
AND (c_bill.begn_eff_dt <= SYSDATE)
START WITH c_bill.bom_doc_nbr=RPAD(?,25)
CONNECT BY PRIOR c_bill.comp_part_nbr=c_bill.bom_doc_nbr
AND c_bill.view_code IN ('M','G')
AND c_bill.status = 'RL'
AND c_bill.end_eff_dt > SYSDATE
AND c_bill.begn_eff_dt <= SYSDATE
) a
WHERE c_part_type = 'M'The outside criterion of part_type='M' isn't my problem. Where I'm actually seeing my issue rear its ugly head is in the criterion:
(c_bill.view_code IN ('M','G'))What I'll have happen is that one of the children or grandchildren of the part number I'm querying for (my parameter), will be of some view code that's not 'M' or 'G'. In my sample data below, I have a level 4 part that is part of the 'H' view code, which I don't want, nor do I want it's children. However, its child is in the 'G' view code, and my query returns it anyway.
In my sample data below, I'm assuming that the parameter = 'XYZ-100'
CREATE TABLE part
part_nbr varchar(25) not null,
part_desc varchar(25) not null,
part_type char(1) not null,
qty_on_hand double(13,4) not null
CONSTRAINT part_pk
PRIMARY KEY (part_nbr),
CONSTRAINT check_part_type
CHECK (part_type IN ('M','P','X','Y')),
CONSTRAINT check_qty_on_hand
CHECK (qty_on_hand >= 0)
CREATE TABLE bill
row_added_ts char(20) not null,
bom_doc_nbr varchar(25) not null,
comp_part_nbr varchar(25) not null,
qty_per double(9,5) not null,
qty_per_type char(1) not null,
oper_nbr char(4) not null,
comp_off_adj double(3,0),
status char(2),
view_code char(1) not null,
end_eff_dt date() not null,
begn_eff_dt date() not null
CONSTRAINT bill_pk
PRIMARY KEY (row_added_ts),
CONSTRAINT check_qty_per_type
CHECK (qty_per_type IN ('0','1','2','3')),
CONSTRAINT check_status
CHECK (status IN ('IN', 'RL')),
); Values for those tables:
INSERT INTO part
VALUES ('xyz-1', 'purchased part', 'P', 5);
INSERT INTO part
VALUES ('xyz-2', 'purchased part', 'P', 1);
INSERT INTO part
VALUES ('xyz-3', 'purchased part', 'P', 1);
INSERT INTO part
VALUES ('xyz-3a', 'manufactured part', 'M', 1);
INSERT INTO part
VALUES ('xyz-4', 'purchased part', 'P', 1);
INSERT INTO part
VALUES ('xyz-9-1', 'manufactured part', 'M', 0);
INSERT INTO part
VALUES ('xyz-9a', 'manufactured part', 'M', 0);
INSERT INTO part
VALUES ('raw-1', 'purchased raw material', 'P', 212);
INSERT INTO part
VALUES ('raw-2', 'purchased raw material', 'P', 75.5);
INSERT INTO part
VALUES ('XYZ-100', 'manufactured part', 'M', 0);
INSERT INTO part
VALUES ('(OPEN)', '(not in use)', 'Y', 0);
INSERT INTO part
VALUES ('XYZ-100-1', 'manufactured part', 'M', 0);
INSERT INTO part
VALUES ('XYZ-100-2', 'manufactured part', 'M', 1);
INSERT INTO part
VALUES ('XYZ-100-3', 'manufactured part', 'M', 0);
INSERT INTO part
VALUES ('XYZ-100-4', 'manufactured part', 'M', 2);
INSERT INTO part
VALUES ('XYZ-100-A', 'manufactured part', 'M', 0);
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100','xyz-1',3,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100','XYZ-100-1',1,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-1','xyz-1',2,'1','****',1,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-1','XYZ-100-2',3,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-2','xyz-2',6,'1','****',2,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-2','xyz-4',6,'1','****',2,'IN','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-2','xyz-100-3',1,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-3','xyz-3',8,'1','****',1,'RL','M','01-Jan-2050','01-Jan-2000');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-3','xyz-3a',8,'1','****',1,'RL','M','01-Jan-2000','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-3','XYZ-100-4',4,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-3','XYZ-100-A',2,'1','****',2,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008071153100150000','XYZ-100-3','(OPEN)',2,'1','****',0,'RL','E','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008071153100150000','XYZ-100-3','xyz-9-1',2,'1','****',0,'RL','H','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-4','raw-1',8.75,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008072153100150000','XYZ-100-A','raw-2',3.75,'1','****',0,'RL','M','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008075911100150000','xyz-9-1','xyz-9a',1,'1','****',0,'RL','G','01-Jan-2050','01-Jan-1900');
INSERT INTO bill
VALUES ('2008087711100150000','xyz-9a','raw-2',3.75,'1','****',0,'RL','G','01-Jan-2050','01-Jan-1900');Sample data displayed in table format:
--PART table (from insert statements above)
part_nbr part_desc part_type qty_on_hand
xyz-1 purchased part P 5
xyz-2 purchased part P 1
xyz-3 purchased part P 1
xyz-3a manufactured part M 1
xyz-4 purchased part P 1
xyz-9-1 manufactured part M 0
xyz-9a manufactured part M 0
raw-1 purchased raw material P 212
raw-2 purchased raw material P 75.5
XYZ-100 manufactured part M 0
(OPEN) (not in use) Y 0
XYZ-100-1 manufactured part M 0
XYZ-100-2 manufactured part M 1
XYZ-100-3 manufactured part M 0
XYZ-100-4 manufactured part M 2
XYZ-100-A manufactured part M 0
--BILL table (from insert statements above)
row_added_ts bom_doc_nbr comp_part_nbr qty_per qty_per_type oper_nbr comp_off_adj status view_code end_eff_dt begn_eff_dt
2008072153100150000 XYZ-100 xyz-1 3 1 **** 0 RL G 01-Jan-2050 01-Jan-1900
2008072223100150000 XYZ-100 XYZ-100-1 1 1 **** 0 RL M 01-Jan-2050 01-Jan-1900
2008072411100150000 XYZ-100-1 xyz-1 2 1 **** 1 RL M 01-Jan-2050 01-Jan-1900
2008072459100150000 XYZ-100-1 XYZ-100-2 3 1 **** 0 RL M 01-Jan-2050 01-Jan-1900
2008072578100150000 XYZ-100-2 xyz-2 6 1 **** 2 RL M 01-Jan-2050 01-Jan-1900
2008072694100150000 XYZ-100-2 xyz-4 6 1 **** 2 IN G 01-Jan-2050 01-Jan-1900
2008072786100150000 XYZ-100-2 xyz-100-3 1 1 **** 0 RL M 01-Jan-2050 01-Jan-1900
2008072865100150000 XYZ-100-3 xyz-3 8 1 **** 1 RL M 01-Jan-2050 01-Jan-2000
2008073100100150000 XYZ-100-3 xyz-3a 8 1 **** 1 RL M 01-Jan-2000 01-Jan-1900
2008073159100150000 XYZ-100-3 XYZ-100-4 4 1 **** 0 RL M 01-Jan-2050 01-Jan-1900
2008073346100150000 XYZ-100-3 XYZ-100-A 2 1 **** 2 RL M 01-Jan-2050 01-Jan-1900
2008073478100150000 XYZ-100-3 (OPEN) 2 1 **** 0 RL E 01-Jan-2050 01-Jan-1900
2008073529100150000 XYZ-100-3 xyz-9-1 2 1 **** 0 RL H 01-Jan-2050 01-Jan-1900
2008073798100150000 XYZ-100-4 raw-1 8.75 1 **** 0 RL M 01-Jan-2050 01-Jan-1900
2008073811100150000 XYZ-100-A raw-2 3.75 1 **** 0 RL M 01-Jan-2050 01-Jan-1900
2008075911100150000 xyz-9-1 xyz-9a 1 1 **** 0 RL G 01-Jan-2050 01-Jan-1900
2008087711100150000 xyz-9a raw-2 3.75 1 **** 0 RL G 01-Jan-2050 01-Jan-1900--What I want to get with my query (branches pruned off my tree)
LEVEL C_PART_NBR C_PART_DESC C_PART_TYPE C_QTY_PER_P C_QTY_PER_TYPE C_QTY_ON_HAND RQD_AT_OP RQD_OFFSET P_PART_NBR P_QTY_ON_HAND
1 XYZ-100-1 manufactured part M 1 1 0 **** 0 XYZ-100 0
2 XYZ-100-2 manufactured part M 3 1 1 **** 0 XYZ-100-1 0
3 xyz-100-3 manufactured part M 1 1 0 **** 0 XYZ-100-2 1
4 XYZ-100-4 manufactured part M 4 1 2 **** 0 XYZ-100-3 0
4 XYZ-100-A manufactured part M 2 1 0 **** 2 XYZ-100-3 0--What I actually get with my query (includes children of items that don't meet query criteria)
LEVEL C_PART_NBR C_PART_DESC C_PART_TYPE C_QTY_PER_P C_QTY_PER_TYPE C_QTY_ON_HAND RQD_AT_OP RQD_OFFSET P_PART_NBR P_QTY_ON_HAND
1 XYZ-100-1 manufactured part M 1 1 0 **** 0 XYZ-100 0
2 XYZ-100-2 manufactured part M 3 1 1 **** 0 XYZ-100-1 0
3 xyz-100-3 manufactured part M 1 1 0 **** 0 XYZ-100-2 1
4 XYZ-100-4 manufactured part M 4 1 2 **** 0 XYZ-100-3 0
4 XYZ-100-A manufactured part M 2 1 0 **** 2 XYZ-100-3 0
5 xyz-9a manufactured part M 1 1 0 **** 0 xyz-9-1 0Edited by: user11033437 on Jul 30, 2009 7:27 AM (grammar) -
Using depth first traversal to add a new node to a tree with labels
Hello,
I'm currently trying to work my way through Java and need some advice on using and traversing trees. I've written a basic JTree program, which allows the user to add and delete nodes. Each new node is labelled in a sequential order and not dependent upon where they are added to the tree.
Basically, what is the best way to add and delete these new nodes with labels that reflect their position in the tree in a depth-first traversal?
ie: the new node's label will correctly reflect its position in the tree and the other labels will change to reflect this addition of a new node.
I've searched Google and can't seem to find any appropriate examples for this case.
My current code is as follows,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
public class BasicTreeAddDelete extends JFrame implements ActionListener
private JTree tree;
private DefaultTreeModel treeModel;
private JButton addButton;
private JButton deleteButton;
private int newNodeSuffix = 1;
public BasicTreeAddDelete()
setTitle("Basic Tree with Add and Delete Buttons");
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Root");
treeModel = new DefaultTreeModel(rootNode);
tree = new JTree(treeModel);
JScrollPane scrollPane = new JScrollPane(tree);
getContentPane().add(scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
addButton = new JButton("Add Node");
addButton.addActionListener(this);
panel.add(addButton);
getContentPane().add(panel, BorderLayout.SOUTH);
deleteButton = new JButton("Delete Node");
deleteButton.addActionListener(this);
panel.add(deleteButton);
getContentPane().add(panel, BorderLayout.SOUTH);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 300);
setVisible(true);
public void actionPerformed(ActionEvent event)
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if(event.getSource().equals(addButton))
if (selectedNode != null)
// add the new node as a child of a selected node at the end
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node" + newNodeSuffix++);
treeModel.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());
//make the node visible by scrolling to it
TreeNode[] totalNodes = treeModel.getPathToRoot(newNode);
TreePath path = new TreePath(totalNodes);
tree.scrollPathToVisible(path);
else if(event.getSource().equals(deleteButton))
//remove the selected node, except the parent node
removeSelectedNode();
public void removeSelectedNode()
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if (selectedNode != null)
//get the parent of the selected node
MutableTreeNode parent = (MutableTreeNode)(selectedNode.getParent());
// if the parent is not null
if (parent != null)
//remove the node from the parent
treeModel.removeNodeFromParent(selectedNode);
public static void main(String[] arg)
BasicTreeAddDelete basicTree = new BasicTreeAddDelete();
} Thank you for any help.> Has anybody got any advice, help or know of any
examples for this sort of problem.
Thank you.
Check this site: http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JTree.html -
Hierarchical Query with Rollup Sum (CONNECT BY with GROUP BY ROLLUP)
Hi all,
Imagine the following scenario: i have an ACCOUNT table which holds accounts and their hierarchy (currently 5 levels), and a BALANCE table which holds balance records for the accounts. Only CHILD accounts (level 5) have records in the BALANCE table. Simple example:
CREATE TABLE accounts (account_code VARCHAR2(30), parent_account VARCHAR2(30), account_desc VARCHAR2(400));
CREATE TABLE balances (account_code VARCHAR2(30), balance_amount NUMBER(18,2));
INSERT INTO ACCOUNTS VALUES ('TOT',NULL,'Total');
INSERT INTO ACCOUNTS VALUES ('ANA1','TOT','General Expenses');
INSERT INTO ACCOUNTS VALUES ('4801001','ANA1','Small Expenses');
INSERT INTO ACCOUNTS VALUES ('4801002','ANA1','Transportation');
INSERT INTO ACCOUNTS VALUES ('ANA2','TOT','Health Expenses');
INSERT INTO ACCOUNTS VALUES ('4802001','ANA2','Healthcare');
INSERT INTO ACCOUNTS VALUES ('4802002','ANA2','Facilities');
INSERT INTO BALANCES VALUES ('4801001', 2000);
INSERT INTO BALANCES VALUES ('4801002', 1000);
INSERT INTO BALANCES VALUES ('4802001', 3000);
INSERT INTO BALANCES VALUES ('4802002', 4000);What i need in this scenario is to run a hierarchical query, where for each node i compute the sum of all its children (In LEAF nodes which are the child accounts, this sum is the value in BALANCES itself). Final Result would be:
TOT -> 10000
ANA1 -> 3000
4801001 -> 2000
4801001 -> 1000
ANA2 -> 7000
4802001 -> 3000
4802002 -> 4000I have tried various ways, and found out a workaround which works for a fixed amount of levels, basically it builds the hierarchy and computes the SYS_CONNECT_BY_PATH, then splits this as a regular expression and uses GROUP BY ROLLUP to compute the higher levels. Then i assemble it again, now with the computed values. Below is the example query:
select level
, NVL (vfinal.child_account,'TOTAL') ||' - '||
( SELECT account_desc
FROM accounts
WHERE account_code = vfinal.child_acct ) account_name
, to_char(sum_bal, 'fm999g999g999g990') as rolled_up_balance
from
select coalesce( princ.lvl3, princ.lvl2, princ.lvl1 ) child_acct
, DECODE ( princ.lvl2 , NULL
, NULL
, DECODE ( princ.conta_lvl3, NULL
, princ.conta_lvl1,princ.conta_lvl2 ) ) parent_acct
, sum(princ.balance_amount) sum_bal
from (
select hier.lvl1
, hier.lvl2
, hier.lvl3
, hier.parent_account
, hier.account_code child_acc
, bal.balance_amount
from ( select level
, sys_connect_by_path( account_code, '/' ) hierarchy_acct
, REGEXP_SUBSTR(sys_connect_by_path( account_code, '/' ),'[^/]+',1,3) lvl3
, REGEXP_SUBSTR(sys_connect_by_path( account_code, '/' ),'[^/]+',1,2) lvl2
, REGEXP_SUBSTR(sys_connect_by_path( account_code, '/' ),'[^/]+',1,1) lvl1
, account_code
, parent_account
from accounts acc
where level <= 3
start with parent_account is null
connect by nocycle prior account = parent_account
order siblings by parent_account
) hier
, balances bal
where bal.cod_conta = hier.account_code
) princ
where princ.lvl1 is not null
group by rollup ( princ.lvl1
, princ.lvl2
, princ.lvl3 )
order by princ.conta_lvl1
, princ.conta_lvl2
, princ.conta_lvl3
) vfinal
where child_acct is not null
start with parent_acct is null
connect by nocycle prior child_acct = parent_acctAll said and done, what i need is to do the same thing for infinite levels, because this query has 3 fixed levels. Do you know how can i structure a new query where, independently of the number of levels, the parent sums are all rolled up like this?
Thanks a lot in advance! Best Regards!
Thiago
Edited by: Thiago on Sep 6, 2011 11:31 AM
Edited by: Thiago on Sep 6, 2011 1:01 PMHi,
Thiago wrote:
Hi all,
Imagine the following scenario: i have an ACCOUNT table which holds accounts and their hierarchy (currently 5 levels), and a BALANCE table which holds balance records for the accounts. Only CHILD accounts (level 5) have records in the BALANCE table. Simple example:
CREATE TABLE accounts (account_code VARCHAR2(30), parent_account VARCHAR2(30), account_desc VARCHAR2(400));
CREATE TABLE balances (account_code VARCHAR2(30), balance_amount NUMBER(18,2));
INSERT INTO ACCOUNTS ('TOT',NULL,'Total');
INSERT INTO ACCOUNTS ('ANA1','TOT','General Expenses');
INSERT INTO ACCOUNTS ('4801001','ANA1','Small Expenses');
INSERT INTO ACCOUNTS ('4801002','ANA1','Transportation');
INSERT INTO ACCOUNTS ('ANA2','TOT','Health Expenses');
INSERT INTO ACCOUNTS ('4802001','ANA2','Healthcare');
INSERT INTO ACCOUNTS ('4802002','ANA2','Facilities');
INSERT INTO BALANCES ('4801001', 2000);
INSERT INTO BALANCES ('4801001', 1000);
INSERT INTO BALANCES ('4802001', 3000);
INSERT INTO BALANCES ('4802001', 4000);
Thanks for posting the CREATE TABLE and INSERT statements. Remember why you do it: so that the people who want to help you can re-create the problem and test their ideas. If the statments don't work, then they are not so useful. None of the INSERT statements you posted work: they all need a VALUES keyword. Please test those statments before you post them.
Also, make sure that the reuslts you post correspond to the sample data you post. In your sample data, there are no rows in balances for account_codes '4801002' or '4802002'.
I think you want something like this:
WITH connect_by_results AS
SELECT CONNECT_BY_ROOT account_code AS root_account_code
, account_code
FROM accounts
-- NOTE: No START WITH clause
CONNECT BY parent_account = PRIOR account_code
SELECT c.root_account_code || ' -> '
|| TO_CHAR (SUM (b.balance_amount)) AS txt
FROM connect_by_results c
LEFT OUTER JOIN balances b ON c.account_code = b.account_code
GROUP BY c.root_account_code
; -
Need to populate a hierarchical query results in detail block of WIPTXCFM
Hi All,
I would need to customize WIPTXCFM to populate all layered sub assembly schedule numbers against a Final Assembly schedule number.
Requirement is as soon as User enter a FA schedule number; it should populate all levels Sub Assembly Schedule Numbers under this.
I have thought of 1 approach; need suggestion if there is any better way to achieve this to improve the performance.
My Approach: In custom WIPTXCFM form once the FA schedule number is entered; I can fetch all below level data(e.g Level1, level2 ...etc.)
using a cursor with hierarchical query. Then loop through the cursor and insert them in the block after the FA record.
So would look for your suggestion if there is any other better way to achieve this.
Thanks in adv.
Regards.880860 wrote:
Hi All,
I would need to customize WIPTXCFM to populate all layered sub assembly schedule numbers against a Final Assembly schedule number.
Requirement is as soon as User enter a FA schedule number; it should populate all levels Sub Assembly Schedule Numbers under this.
I have thought of 1 approach; need suggestion if there is any better way to achieve this to improve the performance.
My Approach: In custom WIPTXCFM form once the FA schedule no is entered; I can fetch all below level data(e.g Level1, level2 ...etc.)
using a cursor with hierarchical query. Then loop through the cursor and insert them in the block after the FA record.
As per my findings; this hierarchical query takes longer to fetch the below levels data, around 1.5 mins.
Hello 880860,
If your are talking about EBS customization you can post at {forum:id=475}.
Hope this helps
Maybe you are looking for
-
I use a Mac and have latest OsX.
-
Hi, Is it possible to show the page information (page number, repeating header and footer) in the HTML output? I created a RTF template included page number,header and footer, which are displayed correctly in PDF formatted output.(Header and footer r
-
How do I get my music back when I got iPhone5s??
WHen I got iPhone 5s I lost thousands of songs & a lot of apps. How do I get them back? I also cannot download any apps to my phone now. And can't sync.
-
How do you fix the ringer on the iPhone 4s?
I have an iPhone 4s and the ringer is not working. Works fine in my car with Bluetooth. Checked all my settings, have the latest software... does anyone know how to fix this?
-
Passing Values back from Custom Tag
I'm using custom tags, and I'm trying to pass back values to the JSP page from a tag which is iterating over values it gets from an Array. But for some reason I can't access the values. Here is the Tag: public class MemberHelper extends TagSupport im