Vous ne pouvez pas avoir de pivot "dynamique" car le nombre, les noms et les types de données de toutes les colonnes d'une requête doivent être connus de la base de données avant la requête est réellement exécutée (c'est-à-dire au moment de l'analyse).
Je trouve qu'il est plus facile d'agréger des éléments dans un JSON.
select customer_number,
jsonb_object_agg(label, value) as props
from the_table
group by customer_number
Si votre interface peut gérer directement les valeurs JSON, vous pouvez vous arrêter ici.
Si vous avez vraiment besoin d'une vue avec une colonne par attribut, vous pouvez les utiliser à partir de la valeur 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
Je trouve cela un peu plus facile à gérer lorsque de nouveaux attributs sont ajoutés.
Si vous avez besoin d'une vue avec toutes les étiquettes, vous pouvez créer une procédure stockée pour la créer dynamiquement. Si le nombre d'étiquettes différentes ne change pas trop souvent, ceci peut être une solution :
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;
Créez ensuite la vue en utilisant :
call create_customer_view();
Et dans votre code, utilisez simplement :
select *
from customer_properties;
Vous pouvez programmer cette procédure pour qu'elle s'exécute à intervalles réguliers (par exemple via un cron
travail sous Linux)