在greenplum中的递归查询

时间:2015-01-13 07:42:06

标签: greenplum

我需要在greenplum MPP的子/父表中创建一个breadcrumb字段

原始表有2个字段:父亲,孩子 我需要使用breadcrumb提取视图

例如有此记录

1, 2
1, 3
2, 4
4, 5

我需要提取:

1/2
1/3
1/2/4 
1/2/4/5

等等

Greenplum是一个基于postgresql 8.2的MPP处理引擎。基本上它是一个postgres 但是,给出版本,它不支持8.3中的“with recursive”postgresql功能。

此外,如果我尝试创建一个功能来完成工作,我会遇到其他GP限制

例如,如果我创建一个类似下面的函数


    CREATE OR REPLACE FUNCTION   getBreadCrumb(decimal) RETURNS text AS 'DECLARE
    itemid ALIAS FOR $1;
    itemfullname text;
    itemrecord RECORD;
    BEGIN
        SELECT * INTO itemrecord FROM mytable where father=itemid;
        itemfullname := coalesce(itemfullname, '''') || itemrecord.father::text;
        IF itemrecord.child IS NOT NULL  THEN
           itemfullname := itemfullname || ''/'' || getBreadCrumb(itemrecord.child)::text ;
           RETURN itemfullname;
        ELSE
           RETURN itemfullname;
        END IF;
    END'  LANGUAGE 'plpgsql'

然后尝试从我得到

中选择


    ERROR:  function cannot execute on segment because it accesses relation "mytable" (functions.c:152)

对我而言似乎与greenplum的'无共享'架构有关。

创建面包屑的任何其他想法给我的环境?

提前致谢

1 个答案:

答案 0 :(得分:1)

我在使用层次结构时遇到了类似的问题。解决它的唯一选择是编写一个在主服务器上执行的pl / pgsql函数,它将更新循环中的“hierarchy”字段,如下所示:

初始内容:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2}
3       | 1         | {3}
4       | 3         | {4}
5       | 3         | {5}
6       | 5         | {6}

第一次迭代:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2, 1}
3       | 1         | {3, 1}
4       | 3         | {4, 3}
5       | 3         | {5, 3}
6       | 5         | {6, 5}

第二次迭代:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2, 1}
3       | 1         | {3, 1}
4       | 3         | {4, 3, 1}
5       | 3         | {5, 3, 1}
6       | 5         | {6, 5, 3}

上次迭代:

Node_id | Parent_id | Hierarchy
1       | null      | {1}
2       | 1         | {2, 1}
3       | 1         | {3, 1}
4       | 3         | {4, 3, 1}
5       | 3         | {5, 3, 1}
6       | 5         | {6, 5, 3, 1}

为避免每次迭代完全自联接,您可以进行一项优化是存储额外的“级别”字段并为更新的记录增加它(因为只应考虑更新迭代i上的记录以进行更新在迭代i+1

不幸的是,GPDB不支持with recursive并在段级别执行查询,因此这是唯一的选择