Перечень статей   Терминология   Choose language


Аггрегаты вместо рекурсии


Примеры

Для применения агрегатов в качестве предикатов к нескольким звеньям дерева агрегаты записывают после служебного слова '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;

Тюрин Дмитрий



Перечень статей   Терминология   Choose language