我有一个由父子映射组成的表。
E.g
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,以便产生此输出。 (标有'&lt; - '的行表示由于所述原因该行不应存在)
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'}
......等等。 仍然可以“加入”的行将加入,直到他们没有更多的孩子。 无法再加入的行将保持不变。
答案 0 :(得分: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”列
答案 1 :(得分:0)
您的帖子完全符合WITH RECURSIVE查询:
http://www.postgresql.org/docs/current/static/queries-with.html