sql >> Databáze >  >> RDS >> PostgreSQL

Existuje v PostgreSQL něco jako funkce zip(), která kombinuje dvě pole?

Postgres 9.5 nebo novější

array_agg(array expression) :

array_agg ( anyarray ) → anyarray

Zřetězí všechna vstupní pole do pole jedné vyšší dimenze. (Všechny vstupy musí mít stejnou dimenzi a nemohou být prázdné ani null.)

Toto je náhrada za moji vlastní agregační funkci array_agg_mult() ukázáno níže. Je implementován v C a podstatně rychlejší. Použijte to.

Postgres 9.4

Použijte ROWS FROM konstrukt nebo aktualizovaný unnest() což vyžaduje paralelní rozpojení více polí. Každá může mít jinou délku. Získáte (podle dokumentace):

[...] počet řádků výsledků je v tomto případě počet řádků s největší funkcí, s menšími výsledky doplněnými hodnotami null, aby odpovídaly.

Použijte tuto čistší a jednodušší variantu:

SELECT ARRAY[a,b] AS ab
FROM   unnest('{a,b,c}'::text[] 
            , '{d,e,f}'::text[]) x(a,b);

Postgres 9.3 nebo starší

Jednoduché zip()

Zvažte následující demo pro Postgres 9.3 nebo starší :

SELECT ARRAY[a,b] AS ab
FROM  (
   SELECT unnest('{a,b,c}'::text[]) AS a
        , unnest('{d,e,f}'::text[]) AS b
    ) x;

Výsledek:

  ab
-------
 {a,d}
 {b,e}
 {c,f}

Všimněte si, že obě pole musí mít stejný počet prvků rozpojit paralelně, nebo místo toho získáte křížové spojení.

Můžete to zabalit do funkce, pokud chcete:

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$;

Volejte:

SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);

Stejný výsledek.

zip() do vícerozměrného pole:

Nyní, pokud chcete agregovat tuto novou sadu polí do jednoho dvourozměrného pole, bude to složitější.

SELECT ARRAY (SELECT ...)

nebo:

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

nebo:

SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab
FROM  ...

všechny budou mít za následek stejnou chybovou zprávu (testováno na str. 9.1.5):

CHYBA:Nelze najít typ pole pro datový typ text[]

Ale existuje způsob, jak to obejít, jak jsme se dopracovali k této úzce související otázce.
Vytvořte vlastní agregační funkci:

CREATE AGGREGATE array_agg_mult (anyarray) (
   SFUNC    = array_cat
 , STYPE    = anyarray
 , INITCOND = '{}'
);

A použijte to takto:

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

Výsledek:

{{a,d},{b,e},{c,f}}

Všimněte si dalšího ARRAY[] vrstva! Bez něj a jen:

SELECT array_agg_mult(ARRAY[a,b]) AS ab
FROM ...

Získáte:

{a,d,b,e,c,f}

Což může být užitečné pro jiné účely.

Roll další funkce:

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$;

Volejte:

SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type

Výsledek:

{{a,d},{b,e},{c,f}}


  1. Jak vytvořit trasování SQL pro zachycení událostí serveru SQL

  2. TABLOCK vs TABLOCKX

  3. Jak vrátit všechna zakázaná omezení cizích klíčů v SQL Server (příklad T-SQL)

  4. ORACLE SQL:Získejte všechna celá čísla mezi dvěma čísly