Nie możesz mieć „dynamicznego” elementu przestawnego, ponieważ liczba, nazwy i typy danych wszystkich kolumn zapytania muszą być znane bazie danych przed zapytanie jest faktycznie wykonywane (tj. w czasie analizy).
Uważam, że agregowanie danych w formacie JSON jest łatwiejsze w obsłudze.
select customer_number,
jsonb_object_agg(label, value) as props
from the_table
group by customer_number
Jeśli Twój frontend radzi sobie bezpośrednio z wartościami JSON, możesz się tutaj zatrzymać.
Jeśli naprawdę potrzebujesz widoku z jedną kolumną na atrybut, możesz je z wartości 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
Uważam, że jest to nieco łatwiejsze do zarządzania, gdy dodawane są nowe atrybuty.
Jeśli potrzebujesz widoku ze wszystkimi etykietami, możesz utworzyć procedurę składowaną, aby dynamicznie ją tworzyć. Jeśli liczba różnych etykiet nie zmienia się zbyt często, może to być rozwiązanie:
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;
Następnie utwórz widok za pomocą:
call create_customer_view();
A w kodzie po prostu użyj:
select *
from customer_properties;
Możesz zaplanować wykonywanie tej procedury w regularnych odstępach czasu (np. przez cron
praca w systemie Linux)