PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Desaninhar vários arrays em paralelo


Você vai amar este novo recurso do Postgres 9.4 :
unnest(anyarray, anyarray [, ...])

unnest() com a capacidade muito antecipada (pelo menos por mim) de desaninhar vários arrays em paralelo limpamente . O manual:

expandir várias matrizes (possivelmente de tipos diferentes) para um conjunto de linhas. Isso só é permitido na cláusula FROM;

É uma implementação especial do novo ROWS FROM característica.

Sua função agora pode ser apenas:
CREATE OR REPLACE FUNCTION multi_unnest(_some_id int
                                      , _amounts numeric[]
                                      , _invoices text[])
  RETURNS TABLE (some_id int, amount numeric, invoice text) AS
$func$
SELECT _some_id, u.* FROM unnest(_amounts, _invoices) u;
$func$ LANGUAGE sql;

Ligar:
SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[] 
                        , '{01-2222-05,01-3333-04,01-4444-08}'::text[]);

Claro, a forma simples pode ser substituída por SQL simples (sem função adicional):
SELECT 123 AS some_id, *
FROM unnest('{100, 40.5, 76}'::numeric[]
          , '{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS u(amount, invoice);

Em versões anteriores (Postgres 9.3- ), você pode usar a forma menos elegante e menos segura:
SELECT 123 AS some_id
     , unnest('{100, 40.5, 76}'::numeric[]) AS amount
     , unnest('{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS invoice;

Advertências da antiga forma abreviada:além de não ser padrão ter função set-returning no SELECT list, o número de linhas retornadas seria o menor múltiplo comum do número de elementos de cada array (com resultados surpreendentes para números desiguais). Detalhes nestas respostas relacionadas:
  • Unnest() paralelo e ordem de classificação no PostgreSQL
  • Existe algo como uma função zip() no PostgreSQL que combina dois arrays?

Esse comportamento foi finalmente corrigido com o Postgres 10 . Várias funções de retorno de conjunto no SELECT list produz linhas em "lock-step" agora. Ver:
  • Qual ​​é o comportamento esperado para várias funções de retorno de conjunto na cláusula SELECT?