Thanks for the question, Ofir.
Asked: May 27, 2004 - 8:23 am UTC
Last updated: May 25, 2005 - 3:10 pm UTC
Version: 920
Viewed 1000+ times
You Asked
Hi tom,
your site is amazing! I've been using it for a long time.
I have this question
we have a table (T) that has many trees in it (many hierarchies).
It is in the from of (pk, parent_pk, other fields).
I'm getting a record, which can be anywhere within a tree (top level, leaf, somewhere in the middle) and I need to retrive the entire tree that the record is in.
How can I do it in a single SQL statement?
Thanks,
Ofir
and Tom said...
(always nice to have create tables, sample data to work with...)
but in this case, EMP gives me a good example, we can use it to create three trees pretty easily:
ops$tkyte@ORA9IR2> create table t ( pk int primary key, p_pk references t );
Table created.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> insert into t
2 select empno, decode( mgr , (select empno from scott.emp where ename = 'KING'), to_number(null),
3 mgr )
4 from scott.emp
5 where ename <> 'KING'
6 /
13 rows created.
ops$tkyte@ORA9IR2> select rpad('*',2*level,'*')|| pk
2 from t
3 start with p_pk is null
4 connect by prior pk = p_pk
5 /
RPAD('*',2*LEVEL,'*')||PK
------------------------------------------------------------------------
**7566
****7788
******7876
****7902
******7369
**7698
****7499
****7521
****7654
****7844
****7900
**7782
****7934
13 rows selected.
so, 7566, 7698, 7782 are our "roots", we'll pick an interior, root and leaf node and try them out in that order:
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> variable x number
ops$tkyte@ORA9IR2> exec :x := 7788
PL/SQL procedure successfully completed.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select rpad('*',2*level,'*')|| pk
2 from t
3 start with pk = ( select substr( max(to_char(level,'fm0000000000')||pk ), 11 )
4 from t
5 start with pk = :x
6 connect by prior p_pk = pk )
7 connect by prior pk = p_pk
8 /
RPAD('*',2*LEVEL,'*')||PK
------------------------------------------------------------------------
**7566
****7788
******7876
****7902
******7369
ops$tkyte@ORA9IR2> exec :x := 7698
PL/SQL procedure successfully completed.
ops$tkyte@ORA9IR2> /
RPAD('*',2*LEVEL,'*')||PK
------------------------------------------------------------------------
**7698
****7499
****7521
****7654
****7844
****7900
6 rows selected.
ops$tkyte@ORA9IR2> exec :x := 7934
PL/SQL procedure successfully completed.
ops$tkyte@ORA9IR2> /
RPAD('*',2*LEVEL,'*')||PK
------------------------------------------------------------------------
**7782
****7934
Rating
(5 ratings)
Is this answer out of date? If it is, please let us know via a Comment