PostgreSQL中的Kimball Bridge表

时间:2016-04-07 17:08:20

标签: sql postgresql postgresql-9.4 dimensional-modeling

我试图在PostgreSQL数据库中创建一个桥接表,遵循Kimball数据仓库工具包提到的here方法,这样我就可以支持不确定深度的层次结构。

基本思想是,如果您有节点的树层次结构,则需要一个表,该表为树中的每个可能路径都有一行。

首先,您可以创建父子关系表,如下所示:

BEGIN TRANSACTION;

Create table COMPANY (
COMPANY_KEY INTEGER NOT NULL,
COMPANY_NAME VARCHAR,
PARENT_KEY INTEGER);

INSERT INTO COMPANY VALUES (100,'MICROSOFT',NULL);
INSERT INTO COMPANY VALUES (101,'SOFTWARE',100);
INSERT INTO COMPANY VALUES (102,'CONSULTING',101);
INSERT INTO COMPANY VALUES (103,'PRODUCTS',101);
INSERT INTO COMPANY VALUES (104,'OFFICE',103);
INSERT INTO COMPANY VALUES (105,'VISIO',104);
INSERT INTO COMPANY VALUES (106,'VISIO EUROPE',105);
INSERT INTO COMPANY VALUES (107,'BACK OFFICE',103);
INSERT INTO COMPANY VALUES (108,'SQL SERVER',107);
INSERT INTO COMPANY VALUES (109,'OLAP SERVICES',108);
INSERT INTO COMPANY VALUES (110,'DTS',108);
INSERT INTO COMPANY VALUES (111,'REPOSITORY',108);
INSERT INTO COMPANY VALUES (112,'DEVELOPER TOOLS',103);
INSERT INTO COMPANY VALUES (113,'WINDOWS',103);
INSERT INTO COMPANY VALUES (114,'ENTERTAINMENT',103);
INSERT INTO COMPANY VALUES (115,'GAMES',114);
INSERT INTO COMPANY VALUES (116,'MULTIMEDIA',114);
INSERT INTO COMPANY VALUES (117,'EDUCATION',101);

END TRANSACTION;

从上面的文档中,他们建议使用以下代码从上面创建的表中构建桥表:

WITH REC (root_id, level, company_key, parent_key, company_name, unparsed_company_name)
AS (
    SELECT company_key, 
        1,
        company_key, 
        parent_key, 
        company_name, 
        CAST(company_name AS VARCHAR(250))
    FROM company
    WHERE parent_key IS NULL
    UNION ALL
    SELECT 
        rec.root_id,
        rec.level + 1, 
        rec_plus1.company_key, 
        rec_plus1.parent_key, 
        rec_plus1.company_name, 
        TRIM(rec.unparsed_company_name)||'>'||TRIM(rec_plus1.company_name)
    FROM company AS rec_plus1, rec
    WHERE rec.company_key = rec_plus1.parent_key
)
SELECT 
    company_key,
    parent_key,
    company_name,
    root_id,
    level AS depth_from_parent,
    COALESCE((SELECT 'N' FROM company s2 WHERE s1.company_key = s2.parent_key FETCH FIRST ROW ONLY), 'Y') AS lowest_flag,
    (SELECT (CASE WHEN MAX (s2.level) = s1.level THEN 'Y' ELSE 'N' END) FROM rec s2 WHERE s1.root_id = s2.company_key) AS top_most_flag,
    REPEAT('', level*5)||level||'-'||company_name AS company_logical_tree,
    unparsed_company_name FROM rec s1;

我尝试将上述内容转换为PostgreSQL特定代码,如下所示:

BEGIN TRANSACTION;

CREATE TABLE company_bridge AS
WITH RECURSIVE rec (root_id, level, company_key, parent_key, company_name, unparsed_company_name)
AS (
    SELECT company_key::integer, 
        1, 
        company_key::integer, 
        parent_key::integer, 
        company_name::varchar, 
        company_name::varchar
    FROM company
    WHERE parent_key IS NULL
    UNION ALL
    SELECT 
        rec.root_id,
        rec.level + 1, 
        rec_plus1.company_key, 
        rec_plus1.parent_key, 
        rec_plus1.company_name, 
        (TRIM(rec.unparsed_company_name)||'>'||TRIM(rec_plus1.company_name))::varchar
    FROM company AS rec_plus1, rec
    WHERE rec.company_key = rec_plus1.parent_key
)
SELECT 
    company_key,
    parent_key,
    company_name,
    root_id,
    level AS depth_from_parent,
    COALESCE((SELECT 'N'::varchar FROM company AS s2 WHERE s1.company_key = s2.parent_key FETCH FIRST ROW ONLY), 'Y'::varchar) AS lowest_flag,
    (SELECT (CASE WHEN MAX (s2.level) = s1.level THEN 'Y'::varchar ELSE 'N'::varchar END) FROM rec AS s2 WHERE s1.root_id = s2.company_key) AS top_most_flag,
    REPEAT('', level*5)||level||'-'||company_name AS company_logical_tree,
    unparsed_company_name FROM rec AS s1;
ALTER TABLE company_bridge ADD PRIMARY KEY (company_key);

END TRANSACTION;

然而,这会产生这个输出,它只有从每个父节点到其直接子节点的行:

Bridge Table Result

我需要的是每个父节点到它下面的每个节点的一行。为了帮助实现这一点,以上表格绘制为树形图:

Tree Diagram

从顶部节点100开始,它应该有一行:100-100(本身),100-> 101,100-> 102,100-> 103 ...一直到100 - > 117 - 即树中的每个节点。下一个节点101对于它下面的每个节点应该具有相同的,包括其自身:101-> 101,101-> 102 ... 101-> 117。树下面的节点,如108,将具有:108-> 108,108-> 109,108-> 110和108-> 111.

我只是习惯在Postgres中使用递归,所以我很难诊断出问题所在。有什么想法吗?

0 个答案:

没有答案