有什么样PostgreSQL中的zip()函数将两个数组? [英] Is there something like a zip() function in PostgreSQL that combines two arrays?
问题描述
我也有同样长度的两个数组值在PostgreSQL的:
{A,B,C}
和 {D,E,F}
和我想将它们合并为
{{A,D},{B,E},{C,F}}
有没有办法做到这一点?
的Postgres 9.3或以上
简单的ZIP()
考虑下面的演示Postgres的 9.3或更早版本
SELECT ARRAY [A,B] AS AB
FROM(
SELECT UNNEST('{A,B,C}'::文[])作为一个
,UNNEST为B('{D,E,F}'::文[])
) X;
结果:
AB
-------
{广告}
{是}
{C,F}
请注意,这两个数组必须具有的相同数量的元素的并行UNNEST,或者你会得到一个交叉连接来代替。
您可以换到这一功能,如果你想:
CREATE OR REPLACE FUNCTION拉链(anyarray的,anyarray的)
RETURNS SETOF anyarray的语言SQL AS
$ FUNC $
SELECT ARRAY [A,B] FROM(SELECT UNNEST($ 1)作为,UNNEST为B($ 2))×;
$ FUNC $;
电话:
SELECT拉链('{A,B,C}'::文本[],'{D,E,F}'::文[]);
同样的结果。
的zip(),以多维数组:
现在,如果你想为总新阵列集为一体的 2 dimenstional 阵列,它变得更加复杂。
<击>选择Array(SELECT ...)击>
或
<击> SELECT ARRAY_AGG(ARRAY [A,B])作为AB
FROM(
SELECT UNNEST('{A,B,C}'::文[])作为一个
,UNNEST为B('{D,E,F}'::文[])
)X 罢工>
或
<击> SELECT ARRAY_AGG(ARRAY [ARRAY [A,B])AS AB
FROM ... 击>
都将导致相同的错误消息(带PG 9.1.5测试):
错误:无法找到数据类型的文本数组类型[]
块引用>但有解决的办法,因为我们在此密切相关的问题的制定。结果
创建自定义聚合函数:CREATE AGGREGATE array_agg_mult(anyarray的)(
SFUNC = array_cat
,STYPE = anyarray的
,INITCOND ='{}'
);和使用这样的:
SELECT array_agg_mult(ARRAY [ARRAY [A,B])AS AB
FROM(
SELECT UNNEST('{A,B,C}'::文[])作为一个
,UNNEST为B('{D,E,F}'::文[])
) X结果:
{{A,D},{B,E},{C,F}}
请注意额外的
[]数组
图层!如果没有它,只是:SELECT array_agg_mult(ARRAY [A,B])作为AB
FROM ...您可以:
{A,D,B,E,C,F}
其中可以是用于其它目的。
滚动另一个功能:
CREATE OR REPLACE FUNCTION ZIP2(anyarray的,anyarray的)
RETURNS SETOF anyarray的语言SQL AS
$ FUNC $
SELECT array_agg_mult(ARRAY [ARRAY [A,B])
FROM(SELECT UNNEST($ 1)为A,UNNEST为B($ 2))×;
$ FUNC $;电话:
SELECT拉链码('{A,B,C}'::文本[],'{D,E,F}'::文[]); - 或任何其他阵列型
结果:
{{A,D},{B,E},{C,F}}
Postgres的9.4±
使用FROM 的
ROWS建造或更新<code> UNNEST()
这需要多个阵列并行UNNEST。每一个都可以具有不同的长度。你得到(<一个href=\"http://www.postgresql.org/docs/9.4/interactive/queries-table-ex$p$pssions.html#QUERIES-TABLEFUNCTIONS\">per文档):
...]结果行的在这种情况下的数量是最大的功能
因此,用空值填充较小的结果相匹配。
块引用>使用此清洁剂和无处不在下面简单的变体:
SELECT ARRAY [A,B] AS AB
从UNNEST('{A,B,C}'::文本[]
{D,E,F}'::文[])×(A,B);的Postgres 9.5 +
船舶内置的我的自定义版本
array_agg_mult()
用C这是相当快实现。 <一href=\"http://www.postgresql.org/docs/9.5/interactive/functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE\">The文档:函数参数类型(S)返回类型
ARRAY_AGG(如pression)任何数组类型相同的参数的数据类型描述
输入数组串连成一个高维数组
(投入必须都具有相同的维度,并且不能为空或NULL)
块引用>这是一个下拉更换为我的自定义聚合函数
array_agg_mult()
。使用它。I have two array values of the same length in PostgreSQL:
{a,b,c}
and{d,e,f}
and I'd like to combine them into
{{a,d},{b,e},{c,f}}
Is there a way to do that?
解决方案Postgres 9.3 or older
Simple zip()
Consider the following demo for Postgres 9.3 or earlier:
SELECT ARRAY[a,b] AS ab FROM ( SELECT unnest('{a,b,c}'::text[]) AS a ,unnest('{d,e,f}'::text[]) AS b ) x;
Result:
ab ------- {a,d} {b,e} {c,f}
Note that both arrays must have the same number of elements to unnest in parallel, or you get a cross join instead.
You can wrap this into a function, if you want to:
CREATE OR REPLACE FUNCTION zip(anyarray, anyarray) RETURNS SETOF anyarray LANGUAGE SQL AS $func$ SELECT ARRAY[a,b] FROM (SELECT unnest($1) AS a, unnest($2) AS b) x; $func$;
Call:
SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);
Same result.
zip() to multi-dimensional array:
Now, if you want to aggregate that new set of arrays into one 2-dimenstional array, it gets more complicated.
SELECT ARRAY (SELECT ...)or:
SELECT array_agg(ARRAY[a,b]) AS ab FROM ( SELECT unnest('{a,b,c}'::text[]) AS a ,unnest('{d,e,f}'::text[]) AS b ) xor:
SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab FROM ...will all result in the same error message (tested with pg 9.1.5):
ERROR: could not find array type for data type text[]
But there is a way around this, as we worked out under this closely related question.
Create a custom aggregate function:CREATE AGGREGATE array_agg_mult (anyarray) ( SFUNC = array_cat ,STYPE = anyarray ,INITCOND = '{}' );
And use it like this:
SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) AS ab FROM ( SELECT unnest('{a,b,c}'::text[]) AS a ,unnest('{d,e,f}'::text[]) AS b ) x
Result:
{{a,d},{b,e},{c,f}}
Note the additional
ARRAY[]
layer! Without it and just:SELECT array_agg_mult(ARRAY[a,b]) AS ab FROM ...
You get:
{a,d,b,e,c,f}
Which may be useful for other purposes.
Roll another function:
CREATE OR REPLACE FUNCTION zip2(anyarray, anyarray) RETURNS SETOF anyarray LANGUAGE SQL AS $func$ SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) FROM (SELECT unnest($1) AS a, unnest($2) AS b) x; $func$;
Call:
SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type
Result:
{{a,d},{b,e},{c,f}}
Postgres 9.4+
Use the
ROWS FROM
construct or the updatedunnest()
which takes multiple arrays to unnest in parallel. Each can have a different length. You get (per documentation):[...] the number of result rows in this case is that of the largest function result, with smaller results padded with null values to match.
Use this cleaner and simpler variant everywhere below:
SELECT ARRAY[a,b] AS ab FROM unnest('{a,b,c}'::text[] , '{d,e,f}'::text[]) x(a,b);
Postgres 9.5+
ships a built-in version of my custom
array_agg_mult()
implemented in C which is considerably faster. The documentation:Function Argument Type(s) Return Type array_agg(expression) any array type same as argument data type Description input arrays concatenated into array of one higher dimension (inputs must all have same dimensionality, and cannot be empty or NULL)
This is a drop-in replacement for my custom aggregate function
array_agg_mult()
. Use it.这篇关于有什么样PostgreSQL中的zip()函数将两个数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!