Аггрегаты вместо рекурсии
Примеры
Для применения агрегатов в качестве предикатов
к нескольким звеньям дерева
агрегаты записывают после служебного слова 'where'
update p/q/r/a.b[@b1 as @m]*.c[@c1 as @n]* -- rational tree
set @a1=5, @b2=10
where sum(@m)+sum(@n)>1;
|
update tab/@fld/p/q/r/a.b[@b1 as @m]*.c[@c1 as @n]* -- xml-tree
set @a1=5, @b2=10
where sum(@m)+sum(@n)>1;
|
или после служебного слова 'select'
select sum(@b1) as @m, sum(@c1) as @n
from a.b*.c* ;
|
Сравнения
Например, для нахождения самого дешевого маршрута между городами
create table city (
id number primary key,
name varchar
);
create table price (
id1 number references city (id),
id2 number references city (id),
cost money
);
мы могли бы написать лаконично и прозрачно, используя
XTree и
виртуальный внешний ключ
select sum(@price)
from city[@id=5].price*.city[@id=700]
where previous(price)/@id2=next(price)/@id1;
вместо громоздкого выражения
with recursive res (@id1, @id2, @total) as (
select @id1, @id2, @cost
from price
where @id1=5
union
select res/@id1, price/@id2, res/@total+price/@cost
from res, price
where res/@id2=price/@id1
) select @id1, @id2, @total
from res
where @id2=700;
И даже
select min( sum(@price) )
from city[@id=5].price*.city[@id=700]
where previous(price)/@id2=next(price)/@id1;
вместо
with recursive res (@id1, @id2, @total) as (
select @id1, @id2, @cost
from price
where @id1=5
union
select res/@id1, price/@id2, res/@total+price/@cost
from res, price
where res/@id2=price/@id1
) select @id1, @id2, min(@total)
from res
where @id2=700;
Тюрин Дмитрий