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

Como você pode expandir uma linha condensada do PostgreSQL em colunas separadas?

9.3 e superior:consulta lateral


No PostgreSQL 9.3 ou mais recente, use uma consulta lateral implícita:
SELECT f.* FROM things t, some_function(t.thing_id) f;

Prefira esta formulação para todas as novas consultas . O acima é a formulação padrão .

Ele também funciona corretamente com funções que RETURNS TABLE ou RETURNS SETOF RECORD bem como funções com out-params que RETURNS RECORD .

É uma abreviação para:
SELECT f.*
FROM things t
CROSS JOIN LATERAL some_function(t.thing_id) f;

Pré-9.3:expansão curinga (com cuidado)


Versões anteriores causam avaliação múltipla de some_function , não funciona se some_function retorna um conjunto, não use isso :
SELECT (some_function(thing_id)).* FROM things;

Versões anteriores, evita a avaliação múltipla de some_function usando uma segunda camada de indireção. Use isso apenas se você precisar suportar versões bastante antigas do PostgreSQL.
SELECT (f).*
FROM (
  SELECT some_function(thing_id) f
  FROM things
) sub(f);

Demonstração:


Configurar:
CREATE FUNCTION some_function(i IN integer, x OUT integer, y OUT text, z OUT text) RETURNS record LANGUAGE plpgsql AS $$
BEGIN
  RAISE NOTICE 'evaluated with %',i;
  x := i;
  y := i::text;
  z := 'dummy';
  RETURN;
END;
$$;

create table things(thing_id integer);
insert into things(thing_id) values (1),(2),(3);

execução de teste:
demo=>     SELECT f.* FROM things t, some_function(t.thing_id) f;
NOTICE:  evaluated with 1
NOTICE:  evaluated with 2
NOTICE:  evaluated with 3
 x | y |   z   
---+---+-------
 1 | 1 | dummy
 2 | 2 | dummy
 3 | 3 | dummy
(3 rows)

demo=>     SELECT (some_function(thing_id)).* FROM things;
NOTICE:  evaluated with 1
NOTICE:  evaluated with 1
NOTICE:  evaluated with 1
NOTICE:  evaluated with 2
NOTICE:  evaluated with 2
NOTICE:  evaluated with 2
NOTICE:  evaluated with 3
NOTICE:  evaluated with 3
NOTICE:  evaluated with 3
 x | y |   z   
---+---+-------
 1 | 1 | dummy
 2 | 2 | dummy
 3 | 3 | dummy
(3 rows)

demo=>  SELECT (f).*
    FROM (
      SELECT some_function(thing_id) f
      FROM things
    ) sub(f);
NOTICE:  evaluated with 1
NOTICE:  evaluated with 2
NOTICE:  evaluated with 3
 x | y |   z   
---+---+-------
 1 | 1 | dummy
 2 | 2 | dummy
 3 | 3 | dummy
(3 rows)