Базы данных
Иерархические данные
select pid from parent where id = :id;
select id from parent where pid = :id;
select aid from ancestor where id = :id;
select id from ancestor where aid = :id;
select aid from ancestor where id = :id and aid not in (select aid from ancestor where id = :aid)
select aid from ancestor where id in (:id1, :id2) group by aid having count(id) = 2
select aid from ancestor where id in (:id1, :id2) group by aid having count(id) = 1
select id from forest where id not in (select id from ancestor)
select id from forest where id not in (select id from parent)
select id from forest where id not in (select aid from ancestor)
select id from forest where id not in (select pid from parent)
select id, count(aid) as depth from forest natural join ancestor group by id
select aid, max(depth) as depth from ancestor natural join forest group by aid;
create table forest ( id int not null primary key, pid int references forest(id), data ... );
create view parent(id, pid, data) as select id, pid, data from forest where pid is not null
create view parent(id, pid, data) as select id, pid, data from forest where pid <> id
create view ancestor(id, aid) as with recursive anc(id, aid) as select id, pid from forest union select forest.id, ancestor.aid from anc inner join forest on forest.pid = acestor.id; select id, aid from anc
insert into forest (id, pid, data) values (:id, null, ...)
insert into forest (id, pid, data) values (:id, :id, ...)
insert into forest (id, pid, data) values (:id, :pid, ...)
delete from forest where id = :id
delete from forest where id = :id or id in (select id from ancestor where aid = :id)
update forest set pid = :id where id = :id
create table forest ( id int not null primary key, l int, r int, data ..., constraint ordered check (l < r) );
create view ancestor(id, aid) as select d.id, a.id from forest d, forest a where d.l between a.l and d.r
create view parents(id, pid) as select c.id, p.id from forest c, forest p where c.l between p.l and p.r and not exists (select * from forest i where (i.l between p.l and p.r) and (c.l between i.l and i.r))
select max(r) + 1 into m from forest; insert into forest (id, l, r, data) values (:id, m + 1, m + 2, ...)
select r in rr from forest where id = :pid; update forest set l = l + 2 where l >= rr; update forest set r = r + 2 where r > = rr; insert into forest (id, l, r, data) values (:id, rr, rr + 1, ...);
select r into rr from forest where id = :id; update forest set l = l - 2 where l > rr; update forest set r = r - 2 where r > rr; delete from forest where id = :id
select l into ll, r into rr from forest where id = :id; delete from forest where l between(ll, rr) update forest set l = l - (rr - ll + 1) where l > rr; update forest set r = r - (rr - ll + 1) where r > rr;
create table forest ( id int not null primary key, path varchar(100) );
create view ancestor(id, aid) as select d.id, a.id from forest d, forest a where a.path like (d.path || '.%')
create view child(id, aid) as select c.id, p.id from forest c, forest p where p.path like (c.path || '.%') and length(p.path) + L + 1 = length(c.path)
insert into forest (id, path, data) values (:id, :label, ...)
insert into forest (id, ppath, data) values (:id, :ppath || '.' || :label, ...)
insert into forest (id, path, data) values ( :id, (select path from forest where id = :pid) || '.' || :label, ... )
delete from forest where id = :id
delete from forest where path like ((select path from forest where id = :id) || ".%")