2011-07-02 6 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」の列を作成しません
関連する問題