PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Trasposizione dinamica per il valore di riga sconosciuto nel nome della colonna su postgres

Non puoi avere un pivot "dinamico" poiché il numero, i nomi e i tipi di dati di tutte le colonne di una query devono essere noti al database prima la query viene effettivamente eseguita (cioè al momento dell'analisi).

Trovo più facile gestire l'aggregazione in un JSON.

select customer_number,
       jsonb_object_agg(label, value) as props
from the_table
group by customer_number

Se il tuo frontend può gestire direttamente i valori JSON, puoi fermarti qui.

Se hai davvero bisogno di una vista con una colonna per attributo, puoi utilizzarle dal valore 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

Trovo che sia un po' più facile da gestire quando vengono aggiunti nuovi attributi.

Se hai bisogno di una vista con tutte le etichette, puoi creare una stored procedure per crearla dinamicamente. Se il numero di etichette diverse non cambia troppo spesso, questa potrebbe essere una soluzione:

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;

Quindi crea la vista utilizzando:

call create_customer_view();  

E nel tuo codice usa semplicemente:

select *
from customer_properties;

È possibile programmare l'esecuzione di tale procedura a intervalli regolari (ad es. tramite un cron lavoro su Linux)