Postgres-连接数组值

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)

如果不是,我想知道这是否与架构设计有关?

Mr.*_*. T 8

不确定这是否仍然对任何人有帮助,但是解除标签嵌套比让 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)


kli*_*lin 5

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。