3

ENV : postgresql-8.4

カテゴリ ツリーを作成しようとしています。基本的に、次のような最終出力を期待しています:

種別名
カテゴリパス
リーフカテゴリ
例:

デジタルカメラ
電化製品 ::: デジタルカメラ
真実

テーブル構造は

CREATE TABLE カテゴリ (
    ID SERIAL PRIMARY KEY,
    カテゴリ ID bigint、
    カテゴリ親 ID bigint、
    カテゴリ名テキスト、
    状態整数 DEFAULT 0,
    言語テキスト、
    eysiteid テキスト、
    国のテキスト、
    控えめなテキスト、
    leafcategory ブール値
);

これまでのところ、私はこれを持っていますが、機能していません。どんな助けでも大歓迎です:

WITH RECURSIVE ツリー (CategoryID、CategoryParentID、CategoryName、category_tree、深さ)
なので (
    選択する
        カテゴリID、
        カテゴリ親ID、
        種別名、
        CategoryName AS カテゴリ_ツリー、
        0 AS深度
    カテゴリから
    WHERE CategoryParentID IS NULL
ユニオンオール
    選択する
        c.CategoryID、
        c.CategoryParentID、
        c.CategoryName、
        tree.category_tree || ツリー.カテゴリツリー || '/' || c.CategoryName AS カテゴリ_ツリー、
        depth+1 AS の深さ
    FROM ツリー
        JOIN カテゴリ c ON (tree.category_tree = c.CategoryParentID)
)
SELECT * FROM ツリー ORDER BY category_tree;

データベースからのサンプル

cat=> カテゴリから * を選択;
  ID | カテゴリ ID | カテゴリ親 ID | カテゴリ名 | ステータス | 言語 | エイサイトイド| 国 | 気まぐれ | リーフカテゴリ
-------+------------+------------------+---------- ----------------------+--------+------+----------- -----------+--------+--------------
     1 | -1 | 0 | ルート | ルート 1 | ja | 0 | 私たち | | | へ
     2 | 20081 | -1 | 骨董品 | 骨董品 1 | ja | 0 | 私たち | | | へ
    17 | 1217 | 20081 | プリミティブ | 0 | ja | 0 | 私たち | | | t
    23 | 22608 | 20081 | 複製骨董品 | 0 | ja | 0 | 私たち | | | t
    24 | 12 | 20081 | その他 | 0 | ja | 0 | 私たち | | | t
    25 | 550 | -1 | アート | アート | 1 | ja | 0 | 私たち | | | へ
    29 | 2984 | -1 | 赤ちゃん | 1 | ja | 0 | 私たち | | | へ

4

2 に答える 2

3

間違ったフィールドに参加していたようです。

 --  create some test data
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE categories
    -- ( id  SERIAL PRIMARY KEY
    ( categoryid SERIAL PRIMARY KEY
    , categoryparentid bigint REFERENCES categories(categoryid)
    , categoryname text
    -- , status integer DEFAULT 0
    -- , lang text
    -- , ebaysiteid text
    -- , country text
    -- , tempid text
    -- , leafcategory boolean
        );
INSERT INTO categories(categoryid,categoryparentid) SELECT gs, 1+(gs/6)::integer
FROM generate_series(1,50) gs;

UPDATE categories SET categoryname = 'Name_' || categoryid::text;
UPDATE categories SET categoryparentid = NULL WHERE categoryparentid <= 0;
UPDATE categories SET categoryparentid = NULL WHERE categoryparentid  >= categoryid;


WITH RECURSIVE tree (categoryid, categoryparentid, categoryname, category_tree, depth)
AS (
    SELECT
        categoryid
        , categoryparentid
        , categoryname
        , categoryname AS category_tree
        , 0 AS depth
    FROM categories
    WHERE categoryparentid IS NULL
UNION ALL
    SELECT
        c.categoryid
        , c.categoryparentid
        , c.categoryname
        , tree.category_tree  || '/' || c.categoryname AS category_tree
        , depth+1 AS depth
    FROM tree
        JOIN categories c ON tree.categoryid  = c.categoryparentid
    )
SELECT * FROM tree ORDER BY category_tree;

編集:再帰の他の(「非関数」)表記はよりうまく機能するようです:

WITH RECURSIVE tree AS (
    SELECT
        categoryparentid AS parent
        , categoryid AS self
        , categoryname AS treepath
        , 0 AS depth
    FROM categories
    WHERE categoryparentid IS NULL
UNION ALL
    SELECT
        c.categoryparentid AS parent
        , c.categoryid AS self
        , t.treepath  || '/' || c.categoryname AS treepath
        , depth+1 AS depth
    FROM categories c
    JOIN tree t ON t.self  = c.categoryparentid
    )
SELECT * FROM tree ORDER BY parent,self
   ;

UPDATE:元のクエリでは、置き換える必要があります

WHERE CategoryParentID IS NULL

に:

WHERE CategoryParentID = 0

または多分:

WHERE COALESCE(CategoryParentID, 0) = 0
于 2012-08-06T19:35:30.967 に答える
0

この要点を見てください。それは多かれ少なかれあなたがやりたいことです。あなたの場合、LTreeマテリアライズドパスPostgresqlの拡張機能を使用したほうがよいでしょう。

于 2012-08-21T15:51:52.263 に答える