create table categories (
id int generated always as identity primary key,
parent_id int references categories(id) on delete cascade,
name text
);
insert into categories(parent_id, name) values
(null, 'Root'), (1, 'Sub-root1'), (1, 'Sub-root2'),
(3, 'Sub-sub-root3');
with recursive cat_tree as (
select id, name from categories where id = 1
union all
select categories.id, categories.name from categories
join cat_tree on cat_tree.id = categories.parent_id
) select * from cat_tree;