如何将 Postgres ltree 加入 table 标签?
How to join a Postgres ltree to a table of labels?
使用 Postgres ltree 存储产品类别的推荐方法是什么?
例如,我的专栏可能包含一个 ltree 路径,例如 "1.2.3"
,其中 1
、2
和 3
是 [=24= 的外键] 可以向用户显示的类别标签:
categories
id | name
---+-----------
1 | Hardware
---+-----------
2 | Computers
---+-----------
3 | Video Cards
---+-----------
现在,对于给定的产品,我想 select 它的类别并将其具体化为 "Hardware > Computers > Video Cards"
。
在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(...)
)。
使用 Postgres ltree 存储产品类别的推荐方法是什么?
例如,我的专栏可能包含一个 ltree 路径,例如 "1.2.3"
,其中 1
、2
和 3
是 [=24= 的外键] 可以向用户显示的类别标签:
categories
id | name
---+-----------
1 | Hardware
---+-----------
2 | Computers
---+-----------
3 | Video Cards
---+-----------
现在,对于给定的产品,我想 select 它的类别并将其具体化为 "Hardware > Computers > Video Cards"
。
在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(...)
)。