Определение количества дочерних путей - PullRequest
1 голос
/ 22 июня 2011

У меня есть таблица, столбец которой «путь» имеет значения, и я хотел бы обновить столбец таблицы «child_count», чтобы я получил следующий вывод.

 path   | child_count 
--------+-------------
        |           5
 /a     |           3
 /a/a   |           0
 /a/b   |           1
 /a/b/c |           0
 /b     |           0

Мое настоящее решение, которое слишком неэффективно, использует хранимую процедуру следующим образом:

CREATE FUNCTION child_count() RETURNS VOID AS $$
DECLARE
  parent VARCHAR; 
BEGIN   
  FOR parent IN
    SELECT path FROM my_table
  LOOP
    DECLARE
      tokens VARCHAR[] := REGEXP_SPLIT_TO_ARRAY(parent, '/');
      str VARCHAR := '';
    BEGIN
      FOR i IN 2..ARRAY_LENGTH(tokens, 1)
      LOOP
        UPDATE my_table
          SET child_count = child_count + 1
        WHERE path = str;
        str := str || '/' || tokens[i];     
      END LOOP;
    END;    
  END LOOP;
END;
$$ LANGUAGE plpgsql;

Кто-нибудь знает об одном операторе UPDATE, который делает то же самое?

Ответы [ 3 ]

0 голосов
/ 22 июня 2011

в TSQL:

update a
set a.child_count = (select count(1) - 1 from my_table as b where b.path like (a.path + '%'))
from my_table as a
0 голосов
/ 22 июня 2011

Управление деревьями в sql не простая тема. Я бы порекомендовал вам попытаться найти хорошую библиотеку, делающую это. Подсчет прямых и косвенных потомков - это лишь малая часть того, что вы, возможно, захотите сделать со своим деревом. И сохранение вашего «количества детей» в базе данных, возможно, не лучшая идея, так как дерево может измениться в будущем.

Я не уверен, что он подойдет для вашей среды разработки, но есть замечательная жемчужина для рельсов под названием ancestry , которая прекрасно справляется с этой задачей (также использует материализованный путь). Но это рубин, и если я вас правильно понимаю, вы захотите реализовать это в postgresql. Тогда я бы порекомендовал вам купить книгу Деревья и иерархии в SQL для умников Джо Селко.

Обновление:

Вот дополнительный модуль postgresql, на который вы можете взглянуть: http://www.postgresql.org/docs/current/static/ltree.html

0 голосов
/ 22 июня 2011

Может быть, что-то вроде этого делает трюк:

UPDATE my_table a
   SET child_count = SELECT count(path) FROM my_table b WHERE b.path LIKE a.path || '/%';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...