Основният проблем с централните таблици в Postgres (и други RDBMS) е, че структурата (броя и имената на колоните) на резултата от заявката не може да варира в зависимост от избраните данни. Едно от възможните решения е динамично създаване на изглед, чиято структура се определя от данните. Функцията за пример създава изглед въз основа на таблицата example_table
:
create or replace function create_pivot_view()
returns void language plpgsql as $$
declare
list text;
begin
select string_agg(format('jdata->>%1$L "%1$s"', name), ', ')
from (
select distinct name
from example_table
) sub
into list;
execute format($f$
drop view if exists example_pivot_view;
create view example_pivot_view as
select lbl, %s
from (
select lbl, json_object_agg(name, value) jdata
from example_table
group by 1
order by 1
) sub
$f$, list);
end $$;
Използвайте функцията след промяна на таблицата (може би в тригер) и заявете създадения изглед:
select create_pivot_view();
select *
from example_pivot_view;
lbl | num | colour | percentage
-----+-----+--------+------------
1 | 1 | Red | 25.0
2 | 2 | Green | 50.0
3 | 3 | Blue | 75.0
(3 rows)
Тествайте го в db<>fiddle.
Имайте предвид, че е необходимо да се създаде отново изглед (извикване на функцията) само след като към таблицата се добави ново име (или някакво име бъде премахнато от него). Ако наборът от различни имена не се промени, можете да направите заявка за изгледа, без да го създавате отново. Ако наборът се променя често, създаването на временен изглед би било по-добър вариант.
Може също да се интересувате от Изравняване на агрегирани двойки ключ/стойност от JSONB поле?