Не можете да имате „динамичен“ пивот, тъй като броят, имената и типовете данни на всички колони на заявка трябва да са известни на базата данни преди заявката действително се изпълнява (т.е. по време на анализ).
Смятам, че събирането на неща в JSON е по-лесно за работа.
select customer_number,
jsonb_object_agg(label, value) as props
from the_table
group by customer_number
Ако интерфейсът ви може да работи директно с JSON стойности, можете да спрете тук.
Ако наистина имате нужда от изглед с една колона на атрибут, можете да ги направите от 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
Намирам това за малко по-лесно за управление, когато се добавят нови атрибути.
Ако имате нужда от изглед с всички етикети, можете да създадете съхранена процедура, за да го създадете динамично. Ако броят на различните етикети не се променя твърде често, това може да е решение:
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;
След това създайте изгледа с помощта на:
call create_customer_view();
И в кода си просто използвайте:
select *
from customer_properties;
Можете да планирате тази процедура да се изпълнява на редовни интервали (напр. чрез cron
работа на Linux)