2015-11-04 33 views
0

PostgreSQL的遞歸抓取整個表

\d brand_categories; 
           Table "public.brand_categories" 
     Column  | Type |       Modifiers 
----------------------+---------+--------------------------------------------------------------- 
id     | integer | not null default nextval('brand_categories_id_seq'::regclass) 
category_code  | text | not null 
correlation_id  | uuid | not null default uuid_generate_v4() 
created_by_id  | integer | not null 
updated_by_id  | integer | not null 
parent_category_code | text | 

我試圖讓所有的家長,並通過WITH RECURSIVE類別的孩子的,但用不了一類的兄弟姐妹下面PostgreSQL的結構。我試着做以下(Ruby代碼中):

WITH RECURSIVE included_categories(category_code) AS (
    SELECT category_code FROM brand_categories 
    WHERE category_code = 'beer' 
    UNION ALL 
    SELECT children.category_code FROM brand_categories AS parents, brand_categories AS children 
     WHERE parents.category_code = children.parent_category_code AND parents.category_code != 'alcohol' 
    UNION SELECT parents.category_code FROM brand_categories AS children, brand_categories AS parents 
     WHERE parents.category_code = children.parent_category_code 
) 
SELECT * from included_categories 

的問題是,它需要一整套的類別,即使大部分是完全無關的。這個查詢有什麼問題嗎?

注意,這與深度2或簡單的分類3.

+1

您是否嘗試在postgresql中直接進行查詢?我的意思是要清楚,如果你需要幫助,使查詢或翻譯成ruby –

+1

然後,也許你應該發佈你在postgresql中嘗試的查詢,而不是使用紅寶石。還可以嘗試用模式和一些數據提供一個 \t \t [** SqlFiddle **](http://sqlfiddle.com/#!15/5368b/6),這樣我們就可以更好地理解問題,甚至給出答案更快 –

+1

您的遞歸查詢('UNION ALL'後面的'SELECT')正在加入'brand_categories'的兩個副本。它應該將'brand_categories'加入'included_categories'。 –

回答

0

我的老闆幫我解決這個問題,它更有意義做兩個部分:

  • 查找所有的父母都
  • 找到所有的孩子

這裏是SQL:

WITH RECURSIVE children_of(category_code) AS (
    SELECT category_code FROM brand_categories WHERE parent_category_code = 'alcohol' 
    UNION ALL 
    SELECT brand_categories.category_code FROM brand_categories 
    JOIN children_of ON brand_categories.parent_category_code = children_of.category_code 
), 
parents_of(parent_category_code) AS (
    SELECT parent_category_code FROM brand_categories WHERE category_code = 'alcohol' 
    UNION 
    SELECT brand_categories.parent_category_code FROM parents_of 
    JOIN brand_categories ON brand_categories.category_code = parents_of.parent_category_code 
) 
SELECT category_code FROM (SELECT * FROM children_of UNION SELECT parent_category_code FROM parents_of) t0(category_code) 
    WHERE category_code IS NOT NULL