如何将Postgres ltree加入标签表?

时间:2015-08-06 18:18:01

标签: postgresql ltree

使用Postgres ltree常用于存储产品类别的推荐方法是什么?

例如,我的列可能包含一个ltree路径,例如"1.2.3"其中123是类别标签表中的外键,可以显示给用户:

categories

id | name
---+-----------
 1 | Hardware
---+-----------
 2 | Computers
---+-----------
 3 | Video Cards
---+-----------

现在,对于给定的产品,我想选择其类别并将其实现为"Hardware > Computers > Video Cards"

1 个答案:

答案 0 :(得分:4)

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子句将向输出添加行号,此处使用别名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(...)