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子句来标识列,然后连接。这取决于数组大小、可用内存、。。我认为,对于更长的阵列,它可以更快。