Emi*_*ray 5 arrays postgresql join aggregate-functions
说我有一个带有模式的表,如下所示
id | name | tags |
1 | xyz | [4, 5] |
Run Code Online (Sandbox Code Playgroud)
其中,标记是对另一个称为标记的表中的ID的引用的数组。
是否可以将这些标签加入行?即用标签表中此行的值替换ID号,例如:
id | name | tags |
1 | xyz | [[tag_name, description], [tag_name, description]] |
Run Code Online (Sandbox Code Playgroud)
如果不是,我想知道这是否与架构设计有关?
不确定这是否仍然对任何人有帮助,但是解除标签嵌套比让 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;
Run Code Online (Sandbox Code Playgroud)
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');
Run Code Online (Sandbox Code Playgroud)
您应该取消column的嵌套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)
Run Code Online (Sandbox Code Playgroud)
或要排列的字符串:
select t.id, t.name, array_agg(concat_ws(', ', g.name, g.description))
...
Run Code Online (Sandbox Code Playgroud)
或字符串中的字符串:
select t.id, t.name, string_agg(concat_ws(', ', g.name, g.description), '; ')
...
Run Code Online (Sandbox Code Playgroud)
或最后但并非最不重要的形式,如jsonb:
select t.id, t.name, jsonb_object_agg(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 | jsonb_object_agg
----+------+------------------------------------------------------------------------
1 | xyz | {"tag_name_4": "tag_description_4", "tag_name_5": "tag_description_5"}
(1 row)
Run Code Online (Sandbox Code Playgroud)
现场演示:db <> fiddle。
| 归档时间: |
|
| 查看次数: |
2410 次 |
| 最近记录: |