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

Transposição dinâmica para valor de linha desconhecido no nome da coluna no postgres


Você não pode ter um pivô "dinâmico", pois o número, os nomes e os tipos de dados de todas as colunas de uma consulta devem ser conhecidos pelo banco de dados antes a consulta é realmente executada (ou seja, no momento da análise).

Acho que agregar coisas em um JSON é mais fácil de lidar.
select customer_number,
       jsonb_object_agg(label, value) as props
from the_table
group by customer_number

Se seu frontend puder lidar com valores JSON diretamente, você pode parar por aqui.

Se você realmente precisa de uma visualização com uma coluna por atributo, você pode a partir do valor JSON:
select customer_number, 
       props ->> 'address' as address,
       props ->> 'phone' as phone,
       props ->> 'email' as email
from (       
  select customer_number,
         jsonb_object_agg(label, value) as props
  from the_table
  group by customer_number
) t

Acho isso um pouco mais fácil de gerenciar quando novos atributos são adicionados.

Se você precisar de uma exibição com todos os rótulos, poderá criar um procedimento armazenado para criá-lo dinamicamente. Se o número de rótulos diferentes não mudar com muita frequência, essa pode ser uma solução:
create procedure create_customer_view() 
as
$$
declare
  l_sql text;
  l_columns text;
begin
  select string_agg(distinct format('(props ->> %L) as %I', label, label), ', ')
    into l_columns
  from the_table;
  
  l_sql := 
    'create view customer_properties as 
     select customer_number, '||l_columns||' 
     from (
      select customer_number, jsonb_object_agg(label, value) as props
       from the_table 
       group by customer_number 
     ) t';
  execute l_sql;
end;
$$
language plpgsql;

Em seguida, crie a visualização usando:
call create_customer_view();  

E no seu código basta usar:
select *
from customer_properties;

Você pode agendar esse procedimento para ser executado em intervalos regulares (por exemplo, por meio de um cron trabalho no Linux)