在Postgres中攀登父/子数据库关系

时间:2009-02-04 19:10:46

标签: sql postgresql recursion

我们有以下示例表(实际上取自stackoverflow上的另一个示例...)

CREATE TABLE example (
  id integer primary key,
  name char(200),
  parentid integer,
  value integer);

给定一个特定的孩子,我们希望得到最好的父母。

我知道tablefunc connectby函数,但这是为了让父母的孩子。

但是,我对另一个方向感兴趣,给一个孩子什么是它的顶级父母?我会尝试使用什么类型的查询?

感谢任何友好的建议。

5 个答案:

答案 0 :(得分:4)

查看Joe Celko的书籍SQL for Smarties及其关于Trees and Hierarchies的书。他在树和层次结构的SQL中有一两个关于Smarties的部分,或者如果你想真正进入它,那么你可以得到另一本书。 SQL for Smarties还将涉及许多其他数据库设计和查询信息。那里有一些非常好的东西。他提出了树木建模的替代方法,它可以比你正在使用的邻接列表模型更好地工作。

在他的一个模型中,“谁是最顶级父母”的问题变得非常微不足道。

答案 1 :(得分:1)

您可以编写PL / PgSQL函数来执行递归:

CREATE LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION get_top_parent(
        child integer
) RETURNS integer as $$
DECLARE
        parent integer;
        last_parent integer;
BEGIN
        last_parent := child;
        SELECT INTO parent parentid
        FROM example
        WHERE id = child;

        IF parent is NOT NULL THEN
                parent := get_top_parent(parent);
        ELSE
                parent := last_parent;
        END IF;
        RETURN parent;
END
$$ LANGUAGE plpgsql;

这个功能绝对可以优化。如果深度非常高并且表格很大,它可能会很慢,所以像Jegern提到的那样,可能值得缓存层次结构,可能使用触发器等。

答案 2 :(得分:1)

您可以考虑使用"ltree" contrib模块。

答案 3 :(得分:1)

从PostgreSQL 8.4开始使用RECURSIVE?

答案 4 :(得分:0)

根据我的经验,SQL在这种查询(递归)方面并不是很擅长。我建议创建一个id和top parent id的附加表。当您添加更多子项时,您只需查找父项的最高父项ID并在附加表中插入相应的行。

您还可以将顶级父ID存储在原始表中。