假设我有一个包含模式的表,如下所示
id | name | tags |
1 | xyz | [4, 5] |
其中tags是另一个名为tags的表中对id的引用数组。
是否可以将这些标签加入到行中?即用标签表中的thise行的值替换id号,例如:
id | name | tags |
1 | xyz | [[tag_name, description], [tag_name, description]] |
如果没有,我想知道这是架构设计的问题吗?
答案 0 :(得分:2)
示例tags
表:
create table tags(id int primary key, name text, description text);
insert into tags values
(4, 'tag_name_4', 'tag_description_4'),
(5, 'tag_name_5', 'tag_description_5');
您应该删除列tags
,使用其元素加入表tags
并聚合最后一个表的列。您可以将数组聚合到数组:
select t.id, t.name, array_agg(array[g.name, g.description])
from my_table as t
cross join unnest(tags) as tag
join tags g on g.id = tag
group by t.id;
id | name | array_agg
----+------+-----------------------------------------------------------------
1 | xyz | {{tag_name_4,tag_description_4},{tag_name_5,tag_description_5}}
(1 row)
或字符串到数组:
select t.id, t.name, array_agg(concat_ws(', ', g.name, g.description))
...
或字符串中的字符串:
select t.id, t.name, string_agg(concat_ws(', ', g.name, g.description), '; ')
...
答案 1 :(得分:2)
不确定这是否仍然对任何人都有用,但是取消标记的嵌套比让postgres直接从数组进行工作要慢得多。您可以重写查询,这样通常会提高性能,因为g.id = ANY(tags)
是简单的pkey索引扫描,无需扩展步骤:
SELECT t.id, t.name, ARRAY_AGG(ARRAY[g.name, g.description])
FROM my_table AS t
LEFT JOIN tags AS g
ON g.id = ANY(tags)
GROUP BY t.id;