sql >> Base de Datos >  >> RDS >> PostgreSQL

Transposición dinámica para valor de fila desconocido en nombre de columna en postgres

No puede tener un pivote "dinámico" ya que la base de datos debe conocer el número, los nombres y los tipos de datos de todas las columnas de una consulta antes la consulta se ejecuta realmente (es decir, en el momento del análisis).

Encuentro que agregar cosas en un JSON es más fácil de manejar.

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

Si su interfaz puede manejar valores JSON directamente, puede detenerse aquí.

Si realmente necesita una vista con una columna por atributo, puede hacerlo desde el 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

Encuentro esto un poco más fácil de administrar cuando se agregan nuevos atributos.

Si necesita una vista con todas las etiquetas, puede crear un procedimiento almacenado para crearlo dinámicamente. Si el número de etiquetas diferentes no cambia con demasiada frecuencia, esta podría ser una solución:

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;

Luego crea la vista usando:

call create_customer_view();  

Y en tu código solo usa:

select *
from customer_properties;

Puede programar ese procedimiento para que se ejecute en intervalos regulares (por ejemplo, a través de un cron trabajo en Linux)