6

次の例のテーブルがあります (実際には、ここのスタックオーバーフローの別の例から取得したものです...)

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

特定の子が与えられた場合、最上位の親を取得したいと考えています。

私は tablefunc connectby 関数を知っていますが、それは親の子を取得するためのものです。

しかし、私は別の方向に興味があります。子供の最上位の親は何ですか? どのタイプのクエリを試して使用しますか?

フレンドリーなアドバイスをいただければ幸いです。

4

5 に答える 5

4

Joe Celkoの本、SQL for Smarties、およびTreesandHierarchiesに関する彼本を調べてください。彼は、SQL for Smartiesのツリーと階層に関するセクションを1つか2つ持っています。または、実際にそれを知りたい場合は、他の本を入手できます。SQL for Smartiesは、他の多くのデータベース設計とクエリ情報にも触れます。そこには本当に良いものがいくつかあります。彼は、使用している隣接リストモデルよりもはるかにうまく機能するツリーをモデル化する別の方法を紹介します。

彼のモデルの1つでは、「誰が一番上の親であるか」という質問は非常に簡単になります。

于 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

PostgreSQL 8.4 以降の WITH RECURSIVE?

于 2009-04-05T22:00:53.987 に答える
1

「ltree」 contrib モジュールの使用を検討してください。

于 2009-02-05T09:41:21.323 に答える
0

私の経験では、SQL はこの種のクエリ (再帰) にはあまり向いていません。ID と最上位の親 ID を持つ追加のテーブルを作成することをお勧めします。子を追加するときは、その親の最上位の親 ID を調べて、追加のテーブルに適切な行を挿入するだけです。

元のテーブルに最上位の親 ID を格納することもできます。

于 2009-02-04T19:15:46.160 に答える