Anda tidak dapat memiliki pivot "dinamis" karena jumlah, nama, dan tipe data dari semua kolom kueri harus diketahui oleh database sebelum kueri benar-benar dieksekusi (yaitu pada waktu parse).
Menurut saya, menggabungkan hal-hal ke dalam JSON lebih mudah untuk ditangani.
select customer_number,
jsonb_object_agg(label, value) as props
from the_table
group by customer_number
Jika frontend Anda dapat menangani nilai JSON secara langsung, Anda dapat berhenti di sini.
Jika Anda benar-benar membutuhkan tampilan dengan satu kolom per atribut, Anda dapat mendapatkannya dari nilai 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
Saya merasa ini sedikit lebih mudah untuk dikelola ketika atribut baru ditambahkan.
Jika Anda memerlukan tampilan dengan semua label, Anda dapat membuat prosedur tersimpan untuk membuatnya secara dinamis. Jika jumlah label yang berbeda tidak terlalu sering berubah, ini mungkin solusinya:
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;
Kemudian buat tampilan menggunakan:
call create_customer_view();
Dan dalam kode Anda cukup gunakan:
select *
from customer_properties;
Anda dapat menjadwalkan prosedur tersebut untuk dijalankan secara berkala (misalnya melalui cron
pekerjaan di Linux)