Базы данных
Иерархические данные
select PId from Parents where Id = :Id;
select Id from Parents where PId = :Id;
select AId from Ancestors where Id = :Id;
select Id from Ancestors where AId = :Id;
select AId from Ancestors
where Id = :Id and
AId not in (select AId from Ancestors where Id = :AId)
select AId from Ancestors where Id in (:Id1, :Id2) group by AId having count(Id) = 2
select AId from Ancestors where Id in (:Id1, :Id2) group by AId having count(Id) = 1
select Id from Forest where
Id not in (select Id from Ancestors)
select Id from Forest where
Id not in (select Id from Parents)
select Id from Forest where
Id not in (select AId from Ancestors)
select Id from Forest where Id
not in (select PId from Parents)
select Id, count(AId) as depth from Forest natural join Ancestors group by Id
select AId, max(depth) as depth from Ancestors natural join Forest group by AId
create table Forest (
Id int not null primary key,
PId int references Forest(Id),
Data ...
);
create view Parents(Id, PId, Data) as select Id, PId, Data from Forest where PId is not null
create view Parents(Id, PId, Data) as select Id, PId, Data from Forest where PId <> Id
create view Ancestors(Id, AId) as
with recursive Anc(Id, AId) as
select Id, PId from Forest
union
select Forest.Id, Ancestors.AId
from Anc inner join Forest
on Forest.PId = Ancestors.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 Ancestors where AId = :Id)
update Forest set PId = :Id where Id = :Id
create table Forest (
Id int not null primary key,
L int not null unique,
R int not null unique,
Data ...,
constraint ordered check (L < R)
);
create view Ancestors(Id, AId) as select D.Id, A.Id from Forest D, Forest A where D.L between A.L and A.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) 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 and 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) unique,
Data ...
);
create view Ancestors(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) || ".%")