在PG 9.4+ 中:
SELECT p.id, string_agg(c.name, ' > ' ORDER BY t.ord) AS label
FROM product p
JOIN regexp_split_to_table(p.category::text, '[.]') WITH ORDINALITY t(category, ord) ON true
JOIN categories c ON c.id = t.category::int
GROUP BY p.id;
这一行:
regexp_split_to_table(p.category::text, '[.]') WITH ORDINALITY t(category, ord)
获取ltree
列,然后将其分成几行,每一行对应ltree
. 该WITH ORDINALITY
子句将在输出中添加一个行号,此处为 alias ord
。该行号用于string_agg()
函数中以保持类别标签的正确顺序。
如果您使用的是旧版本的 PG(9.0+),那么(您应该升级或其他)您应该这样做:
SELECT p.id, string_agg(c.name, ' > ' ORDER BY t.ord) AS label
FROM product p
JOIN generate_series(1, nlevel(p.category)) t(ord) ON true
JOIN categories c ON c.id = subltree(p.category, t.ord - 1, t.ord)::text::int
GROUP BY p.id;
这效率较低,因为ltree
必须为其中包含的每个单独元素解析 ( subltree(...)
)。