PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Czy istnieje coś takiego jak funkcja zip() w PostgreSQL, która łączy dwie tablice?

Postgres 9.5 lub nowszy

ma array_agg(array expression) :

array_agg ( anyarray ) → anyarray

Łączy wszystkie tablice wejściowe w tablicę o jednym wyższym wymiarze. (Wszystkie dane wejściowe muszą mieć tę samą wymiarowość i nie mogą być puste ani puste).

To jest zamiennik dla mojej niestandardowej funkcji agregującej array_agg_mult() pokazane poniżej. Jest zaimplementowany w C i znacznie szybszy. Użyj go.

Postgres 9.4

Użyj ROWS FROM konstrukcja lub zaktualizowana unnest() co wymaga równoległego rozgniecenia wielu tablic. Każdy może mieć inną długość. Otrzymujesz (zgodnie z dokumentacją):

[...] liczba wierszy wyników w tym przypadku odpowiada największemu wynikowi funkcji, z mniejszymi wynikami uzupełnionymi wartościami null do dopasowania.

Użyj tego czystszego i prostszego wariantu:

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

Postgres 9.3 lub starszy

Prosty zip()

Rozważ następujące demo Postgresa 9.3 lub starszego :

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

Wynik:

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

Pamiętaj, że obie tablice muszą mieć tę samą liczbę elementów rozpakować równolegle lub zamiast tego otrzymasz sprzężenie krzyżowe.

Możesz zapakować to w funkcję, jeśli chcesz:

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

Zadzwoń:

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

Ten sam wynik.

zip() do tablicy wielowymiarowej:

Teraz, jeśli chcesz agregować ten nowy zestaw tablic w jeden 2-wymiarowy tablica, robi się bardziej skomplikowana.

SELECT ARRAY (SELECT ...)

lub:

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

lub:

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

wszystkie spowodują ten sam komunikat o błędzie (testowane na stronie 9.1.5):

BŁĄD:nie można znaleźć typu tablicy dla typu danych text[]

Istnieje jednak sposób na obejście tego, ponieważ opracowaliśmy to w ramach tego ściśle powiązanego pytania.
Utwórz niestandardową funkcję agregującą:

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

I użyj go w ten sposób:

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

Wynik:

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

Zwróć uwagę na dodatkowy ARRAY[] warstwa! Bez tego i po prostu:

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

Otrzymujesz:

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

Które mogą być przydatne do innych celów.

Rzuć inną funkcję:

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

Zadzwoń:

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

Wynik:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak napisać zapytanie bez uwzględniania wielkości liter zarówno dla MySQL, jak i Postgres?

  2. Jak działa Acosd() w PostgreSQL

  3. Instalowanie Postgresa w systemie Windows do użytku z Ruby-on-Rails

  4. Wywołanie funkcji lub procedury składowanej nie spowoduje wstawienia i utrwalenia zmian

  5. Grupuj według interwałów danych