有什么样PostgreSQL中的zip()函数将两个数组? [英] Is there something like a zip() function in PostgreSQL that combines two arrays?

查看:216
本文介绍了有什么样PostgreSQL中的zip()函数将两个数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我也有同样长度的两个数组值在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
    ) x

or:

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 updated unnest() 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆