6

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

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

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

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

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

任何友好的建议表示赞赏。

4

5 回答 5

4

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

在他的一个模型中,“谁是最高的父母”这个问题变得非常琐碎。

于 2009-02-04T19:41:45.763 回答
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 提到的那样,缓存层次结构可能是值得的,可能使用触发器等。

于 2009-02-04T19:40:06.373 回答
1

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

于 2009-02-05T09:41:21.323 回答
1

从 PostgreSQL 8.4 开始使用递归?

于 2009-04-05T22:00:53.987 回答
0

以我的经验,SQL 不太擅长这种查询(递归)。我建议创建一个带有 id 和最高父 id 的附加表。当您添加更多孩子时,您只需查找其父级的最高父级 ID 并在附加表中插入适当的行。

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

于 2009-02-04T19:15:46.160 回答