Skip to Main Content
  • Questions
  • How do I get all the ancestors of a given node in a tree using a single SQL query

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: January 05, 2005 - 9:31 pm UTC

Last updated: January 06, 2005 - 5:46 pm UTC

Version: 8.1.7

Viewed 1000+ times

You Asked

Given a node in a tree, I would like write a single SQL query to get all ancestors of that node. The limitations are:

1. The database is external and I have only read access to it.
2. The query needs to be compatible with Oracle 8.1.7

Here is the sample script:

Create Table Tree(
node NUMBER(10),
parentnode NUMBER(10),
)

insert into tree values(1,0);

insert into tree values (11, 1);
insert into tree values (12, 1);
insert into tree values (13, 1);

insert into tree values (2, 0);
insert into tree values (21, 2);
insert into tree values (22, 2);
insert into tree values (23, 2);

insert into tree values (211, 21);
insert into tree values (212, 21);
insert into tree values (213, 21);

insert into tree values (2111, 211);
insert into tree values (2112, 211);
insert into tree values (2113, 211);

For example, the SQL should take 2112 and return 211, 21, 2, 0

P.S: I have used the following query to return the children of 211 & 212 - but don't know how to get the ancestors :

select node FROM tree
START WITH node in (211, 212)
CONNECT BY PRIOR node = parentnode;

I'm a newbie & did search around without much success. Hope you can help!

and Tom said...

If this gets children:

ops$tkyte@ORA9IR2> select rpad('*',2*level,'*' ) || node nd FROM tree
2 START WITH node in (211, 212)
3 CONNECT BY PRIOR node = parentnode;

ND
--------------------
**211
****2111
****2112
****2113
**212


Then, just flip flop the connect by to get "ancestors"


ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select rpad('*',2*level,'*' ) || node nd FROM tree
2 START WITH node in (211, 212)
3 CONNECT BY PRIOR parentnode = node;

ND
--------------------
**211
****21
******2
**212
****21
******2

6 rows selected.


Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Excellent! That worked

Prashant, January 06, 2005 - 5:46 pm UTC

That was a great solution and solved my problem right off the bat!

Earlier I had tried doing this before on my actual db, but I got "ERROR: ORA-01436: CONNECT BY loop in user data" and thought something was wrong not realizing that the root node (start of the hierarchy) had itself as the parent node. To avoid this I also added the condition to exclude the root in the CONNECT BY clause.

Thanks Tom!