ENV:postgresql-8.4
我正在尝试构建一个类别树。基本上我期待最终输出如下:
categoryName categoryPath leafcategory例如:
Digital Camera Electronics ::: Digital Camera true
表格结构是
CREATE TABLE categories ( id SERIAL PRIMARY KEY, categoryid bigint, categoryparentid bigint, categoryname text, status integer DEFAULT 0, lang text, eysiteid text, country text, tempid text, leafcategory boolean );
到目前为止,我已经得到了这个但是没有用。任何帮助将受到高度赞赏:
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.category_tree = c.CategoryParentID) ) SELECT * FROM tree ORDER BY category_tree;
来自数据库的样本
cat=> select * from categories; id | categoryid | categoryparentid | categoryname | status | lang | eysiteid | country | tempid | leafcategory -------+------------+------------------+--------------------------------+--------+------+------------+---------+--------+-------------- 1 | -1 | 0 | Root | 1 | en | 0 | us | | f 2 | 20081 | -1 | Antiques | 1 | en | 0 | us | | f 17 | 1217 | 20081 | Primitives | 0 | en | 0 | us | | t 23 | 22608 | 20081 | Reproduction Antiques | 0 | en | 0 | us | | t 24 | 12 | 20081 | Other | 0 | en | 0 | us | | t 25 | 550 | -1 | Art | 1 | en | 0 | us | | f 29 | 2984 | -1 | Baby | 1 | en | 0 | us | | f
答案 0 :(得分:2)
看来你正在加入错误的领域。
-- 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
;
更新:在原始查询中,您应该替换
WHERE CategoryParentID IS NULL
由:
WHERE CategoryParentID = 0
或者甚至可能:
WHERE COALESCE(CategoryParentID, 0) = 0
答案 1 :(得分:0)
看看this gist它或多或少是你想要做的。在你的情况下,我最好使用LTree materialized path Postgresql's extension。