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

Transformando arbitrariamente muitas linhas em colunas no PostgreSQL


O principal problema com tabelas dinâmicas no Postgres (e outros RDBMS) é que a estrutura (número e nomes das colunas) de um resultado de consulta não pode variar dependendo dos dados selecionados. Uma das soluções possíveis é criar dinamicamente uma visão, cuja estrutura é definida pelos dados. A função de exemplo cria uma visão baseada na tabela example_table :
create or replace function create_pivot_view()
returns void language plpgsql as $$
declare
    list text;
begin
    select string_agg(format('jdata->>%1$L "%1$s"', name), ', ')
    from (
        select distinct name
        from example_table
        ) sub
    into list;

    execute format($f$
        drop view if exists example_pivot_view;
        create view example_pivot_view as
        select lbl, %s
        from (
            select lbl, json_object_agg(name, value) jdata
            from example_table
            group by 1
            order by 1
            ) sub
        $f$, list);
end $$;

Use a função depois que a tabela for modificada (talvez em um gatilho) e consulte a visualização criada:
select create_pivot_view();

select *
from example_pivot_view;

 lbl | num | colour | percentage 
-----+-----+--------+------------
   1 | 1   | Red    | 25.0
   2 | 2   | Green  | 50.0
   3 | 3   | Blue   | 75.0
(3 rows)

Teste no db<>fiddle.

Observe que é necessário recriar uma visão (chamar a função) somente depois que um novo nome for adicionado à tabela (ou algum nome for removido dela). Se o conjunto de nomes distintos não for alterado, você poderá consultar a exibição sem recriá-la. Se o conjunto for modificado com frequência, criar uma visualização temporária seria uma opção melhor.

Você também pode estar interessado em achatar pares de chave/valor agregados de um campo JSONB?