2011-07-02 106 views
3

我有一個由父到子映射組成的表。加入父行到他們的孩子

my_table 
-----+------+--------- 
    id | name | child_id 
-----+------+--------- 
    a | A1 | b 
    b | B1 | c 
    b | B2 | c 
    b | B3 | a 
    c | C1 | d 
    d | D1 | a 
    d | D2 | b 

我想「加入」他們,從而產生這樣的輸出: (行標有「< - 」表明,由於規定的原因,該行應該不存在)

desired_table 
-----+--------+----------+------------- 
    id | name | child_id | visited_ids 
-----+--------+----------+------------- 
    a | A1, B1 | c  | {'a', 'b'} 
    a | A1, B2 | c  | {'a', 'b'} 
    a | A1, B3 | a  | {'a', 'b'} <-- 'a' was visited 
    b | B1, C1 | d  | {'b', 'c'} 
    b | B2, C1 | d  | {'b', 'c'} 
    b | B3, A1 | b  | {'b', 'a'} <-- 'b' was visited 
    c | C1, D1 | a  | {'c', 'd'} 
    c | C1, D2 | b  | {'c', 'd'} 
    d | D1, A1 | b  | {'d', 'a'} 
    d | D2, B1 | c  | {'d', 'b'} 
    d | D2, B2 | c  | {'d', 'b'} 
    d | D2, B3 | a  | {'d', 'b'} 

這個新表中的行將重複'連接'到my_table,以產生此輸出。 (標有行「< - 」表明,由於規定的原因,該行應該不存在)

desired_table 
-----+------------+----------+---------------- 
    id | name | child_id | visited_ids 
-----+------------+----------+---------------- 
    a | A1, B1, C1 | d  | {'a', 'b', 'c'} 
    a | A1, B2, C1 | d  | {'a', 'b', 'c'} 
    b | B1, C1, D1 | a  | {'b', 'c', 'd'} 
    b | B1, C1, D2 | b  | {'b', 'c', 'd'} <-- 'b' was visited 
    b | B2, C1, D1 | a  | {'b', 'c', 'd'} 
    b | B2, C1, D2 | b  | {'b', 'c', 'd'} <-- 'b' was visited 
    c | C1, D1, D1 | a  | {'c', 'd', 'd'} <-- 'd' was visited 
    c | C1, D1, D2 | b  | {'c', 'd', 'd'} <-- 'd' was visited 
    c | C1, D2, B1 | c  | {'c', 'd', 'b'} <-- 'c' was visited 
    c | C1, D2, B2 | c  | {'c', 'd', 'b'} <-- 'c' was visited 
    c | C1, D2, B3 | a  | {'c', 'd', 'b'} 
    d | D1, A1, B1 | c  | {'d', 'a', 'b'} 
    d | D1, A1, B2 | c  | {'d', 'a', 'b'} 
    d | D1, A1, B3 | a  | {'d', 'a', 'b'} 
    d | D2, B1, C1 | d  | {'d', 'b', 'c'} <-- 'd' was visited 
    d | D2, B2, C1 | d  | {'d', 'b', 'c'} <-- 'd' was visited 
    d | D2, B3, A1 | b  | {'d', 'b', 'a'} 

...等等等等。 仍然可以「加入」的行將被合併,直到他們沒有更多的孩子。 不能再加入的行將保持不變。

回答

1

的一個問題是,你有一個無限循環有(a,A1,b) -> (b,B3,a) -> (a,A1,b)這是一個有點棘手檢測。

但是這(和peufeu的鏈接)應該讓你開始:

WITH RECURSIVE hierarchy (id, names, child_id, path) 
AS 
(
    SELECT id, array[name], child_id, array[id] as path 
    FROM mapping 
    WHERE id = 'a' 

    UNION ALL 

    SELECT c.id, p.names||c.name, c.child_id, p.path||c.id 
    FROM mapping c 
    JOIN hierarchy p ON p.child_id = c.id AND NOT (p.path @> (p.path||c.id)) 
) 
SELECT * 
FROM hierarchy 
ORDER BY 1 

,只要你想它雖然

它不會創建「visited_ids」列
相關問題