Reputation: 13
i have table in hsqldb and values like this
How do I write a query that displays like this
Upvotes: 0
Views: 1746
Reputation: 24372
An alternative, simpler query based on the accepted answer. We start only with the roots (rows with null parents) and each time the union is performed, only a few rows are added. As the answer indicates, this kind of query will not select child rows with invalid parent id:
with recursive n (root_id, id, title, parent) as (
select id as root_id, id, name, parent from t where parent is null
union
select n.root_id, t.id, n.title || '/' || t.name, t.parent
from t
join n on n.id = t.parent
)
select * from n
For this kind of table, it is essential to add the referential constraints that are implicit in the design. This will speed up queries when the table gets larger and will also avoid broken parent ids.
alter table t add constraint pk primary key(id)
alter table t add constraint fk foreign key (parent) references t(id)
Upvotes: 0
Reputation: 222672
You can use a recursive query:
with recursive cte (id, name, parent, path, lvl) as
select id, name, parent, name, 0 from mytable
union all
select c.id, c.name, t.parent, concat(t.name, '/', c.path), c.lvl + 1
from cte c
inner join mytable t on t.id = c.parent_id
)
select *
from cte c
where lvl = (select max(c1.lvl) from cte c1 where c1.id = c.id)
The query selects the whole table, then climbs the hierarchy tree of each row. The upside of this approach is that it would properly handle a "broken" tree (like a child with an invalid parent for example).
Upvotes: 1
Reputation: 48865
Here you go:
with recursive
n (root_id, id, title, parent) as (
select id as root_id, id, name, parent from t
union
select n.root_id, t.id, t.name || '/' || n.title, t.parent
from n
join t on t.id = n.parent
)
select title as name from n where parent is null order by root_id
Result:
NAME
----------
A
A/A1
B
B/B1
C
C/C1
A/A1/A2
A/A1/A3
A/A1/A3/A4
B/B1/B3
For reference this is the data script I used to test:
create table t (id int, name varchar(10), parent int);
insert into t (id, name, parent) values
(0, 'A', null),
(1, 'A1', 0),
(2, 'B', null),
(3, 'B1', 2),
(4, 'C', null),
(5, 'C1', 4),
(6, 'A2', 1),
(7, 'A3', 1),
(8, 'A4', 7),
(9, 'B3', 3);
Upvotes: 1