确定路径的子计数

时间:2011-06-22 07:23:27

标签: sql postgresql

我有一个表'path'列有值,我想更新表'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 :(得分:0)

也许这样的事情可以解决问题:

UPDATE my_table a
   SET child_count = SELECT count(path) FROM my_table b WHERE b.path LIKE a.path || '/%';

答案 1 :(得分:0)

在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

答案 2 :(得分:0)

在sql中管理树不是一个简单的主题。我建议你试着找一个好的图书馆。计算直接和间接后代只是您可能想要对树做的一小部分。将“子计数”存储在数据库中可能不是最好的主意,因为树可以在将来发生变化。

我不确定它是否适合您的开发环境,但是对于名为ancestry的rails来说有一个很好的宝石,它可以做得很好(它也使用了物化路径)。但这是红宝石,如果我理解正确,你想在postgresql中实现它。然后我会建议你购买Joe Celko的书Trees and hierarchies in SQL for Smarties

更新:

以下是您可能想要查看的postgresql附加模块:http://www.postgresql.org/docs/current/static/ltree.html