Hovedproblemet med pivottabeller i Postgres (og andre RDBMS) er, at strukturen (antal og navne på kolonner) af et forespørgselsresultat ikke kan variere afhængigt af de valgte data. En af de mulige løsninger er dynamisk at skabe en visning, hvilken struktur er defineret af dataene. Eksempelfunktionen opretter en visning baseret på tabellen 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 $$;
Brug funktionen, efter at tabellen er ændret (måske i en trigger), og forespørg på den oprettede visning:
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)
Test det i db<>fiddle.
Bemærk, at det kun er nødvendigt at genskabe en visning (kald funktionen), når et nyt navn er tilføjet til tabellen (eller et navn er fjernet fra den). Hvis sættet af distinkte navne ikke ændres, kan du forespørge i visningen uden at genskabe den. Hvis sættet ændres ofte, ville oprettelse af en midlertidig visning være en bedre mulighed.
Du er muligvis også interesseret i at udjævne aggregerede nøgle/værdi-par fra et JSONB-felt?