Sql postgres数组到列的数组

Sql postgres数组到列的数组,sql,postgresql,postgresql-9.4,Sql,Postgresql,Postgresql 9.4,我的桌子样本 Table_A id integer arr varchar(20) [] 样本数据 id. arr 1. {{'a', 'b', 'c'}, {'d', 'test1', 'sample1'}} 2. {{'sample2', sample3, sample4'}} 3. null 4. {{'sample6', 'sample7', 'test done'}} 我想选择将数据作为: id. col1. col2

我的桌子样本

Table_A
id integer
arr varchar(20) []
样本数据

id.         arr
1.    {{'a', 'b', 'c'}, {'d', 'test1', 'sample1'}}
2.    {{'sample2', sample3, sample4'}}
3.     null
4.    {{'sample6', 'sample7', 'test done'}}
我想选择将数据作为:

id.     col1.       col2          col3  
1       'a'         'b'.          'c'
1.      'd'.       'test1'.      'sample1'
2.      'sample2'  'sample3'.    'sample4'
3.      null        null          null
4.     'sample6'.  'sample7'.    'test done'
如果
非空
,则保证数据在数组中有5个元素。为方便起见,上面的示例数据包含3个元素。 这是一张相当大的桌子,会随着时间的推移而增加。 现在我正在使用
unnest
然后使用
row\u number()over()
然后使用id连接它们。
有没有更好的方法呢。

只有一种选择——用一些PL语言(如Perl、Python或PLpgSQL)编写过程代码。Perl或Python中的代码将更加动态(您不需要特殊类型),PLpgSQL中的代码很容易编写。对于大型阵列,过程代码可能应该更快

CREATE OR REPLACE FUNCTION unnest_to_columns3(a text[])
RETURNS TABLE(col1 text, col2 text, col3 text)
AS $$
DECLARE r text[];
BEGIN
  FOREACH r SLICE 1 IN ARRAY a 
  LOOP
    col1 := r[1]; col2 := r[2]; col3 := r[3];
    RETURN NEXT;
  END LOOP;
END
$$ LANGUAGE plpgsql;

postgres=# SELECT * FROM unnest_to_columns3('{{a,b,c},{Ahoj,Nazdar,Servus}}');
+------+--------+--------+
| col1 |  col2  |  col3  |
+------+--------+--------+
| a    | b      | c      |
| Ahoj | Nazdar | Servus |
+------+--------+--------+
(2 rows)
注意:PostgreSQL没有数组数组-它只有多维数组

使用记录数组比使用多维数组更实际。这种类型的关系和数组之间有简单的转换

create table foo(v1 text, v2 text, v3 text);
insert into foo values('ahoj','nazdar','servus');
insert into foo values('hi','greating',null);

postgres=# select array_agg(foo) from foo;
+-------------------------------------------+
|                 array_agg                 |
+-------------------------------------------+
| {"(ahoj,nazdar,servus)","(hi,greating,)"} |
+-------------------------------------------+
(1 row)

postgres=# select * from unnest('{"(ahoj,nazdar,servus)","(hi,greating,)"}'::foo[]);
+------+----------+--------+
|  v1  |    v2    |   v3   |
+------+----------+--------+
| ahoj | nazdar   | servus |
| hi   | greating | ∅      |
+------+----------+--------+
(2 rows)

重要提示-关系(表)不是数组,数组也不是关系(表)。

只有一种选择-用一些PL语言(如Perl、Python或PLpgSQL)编写过程代码。Perl或Python中的代码将更加动态(您不需要特殊类型),PLpgSQL中的代码很容易编写。对于大型阵列,过程代码可能应该更快

CREATE OR REPLACE FUNCTION unnest_to_columns3(a text[])
RETURNS TABLE(col1 text, col2 text, col3 text)
AS $$
DECLARE r text[];
BEGIN
  FOREACH r SLICE 1 IN ARRAY a 
  LOOP
    col1 := r[1]; col2 := r[2]; col3 := r[3];
    RETURN NEXT;
  END LOOP;
END
$$ LANGUAGE plpgsql;

postgres=# SELECT * FROM unnest_to_columns3('{{a,b,c},{Ahoj,Nazdar,Servus}}');
+------+--------+--------+
| col1 |  col2  |  col3  |
+------+--------+--------+
| a    | b      | c      |
| Ahoj | Nazdar | Servus |
+------+--------+--------+
(2 rows)
注意:PostgreSQL没有数组数组-它只有多维数组

使用记录数组比使用多维数组更实际。这种类型的关系和数组之间有简单的转换

create table foo(v1 text, v2 text, v3 text);
insert into foo values('ahoj','nazdar','servus');
insert into foo values('hi','greating',null);

postgres=# select array_agg(foo) from foo;
+-------------------------------------------+
|                 array_agg                 |
+-------------------------------------------+
| {"(ahoj,nazdar,servus)","(hi,greating,)"} |
+-------------------------------------------+
(1 row)

postgres=# select * from unnest('{"(ahoj,nazdar,servus)","(hi,greating,)"}'::foo[]);
+------+----------+--------+
|  v1  |    v2    |   v3   |
+------+----------+--------+
| ahoj | nazdar   | servus |
| hi   | greating | ∅      |
+------+----------+--------+
(2 rows)
重要注意事项-关系(表)不是数组,数组也不是关系(表)。

unnest()对于常规多维数组,它会扩展所有维度的所有元素,而不仅仅是第一个维度。所以,对于这些类型的人来说,没有办法做到这一点

一种可能的解决方法是将数组强制转换为JSON数组。对于JSON数组,这不是问题:

json\u array\u elements()。然后简单地通过索引获取元素


上面的查询消除了空行,因为它使用了逗号表示法(实际上,在本例中,逗号表示法是
内部连接的快捷方式)。这可以通过使用
左侧外侧连接横向连接来避免:

常规多维数组的unnest()有一个问题,它扩展所有维度的所有元素,而不仅仅是第一个维度。所以,对于这些类型的人来说,没有办法做到这一点

一种可能的解决方法是将数组强制转换为JSON数组。对于JSON数组,这不是问题:

json\u array\u elements()。然后简单地通过索引获取元素


上面的查询消除了空行,因为它使用了逗号表示法(实际上,在本例中,逗号表示法是
内部连接的快捷方式)。这可以通过使用
左侧外侧连接横向连接来避免:


plpgsql将比连接更快。首先是unnest(are),然后是row_number()over(),带有mod的where子句来标识列,然后连接。这取决于数组大小、可用内存、。。我认为对于一些较长的阵列,它可以更快。plpgsql会比连接更快吗。首先是unnest(are),然后是row_number()over(),带有mod的where子句来标识列,然后连接。这取决于数组大小、可用内存、。。我认为,对于更长的阵列,它可以更快。