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)