PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Trasformare arbitrariamente molte righe in colonne in PostgreSQL

Il problema principale con le tabelle pivot in Postgres (e altri RDBMS) è che la struttura (numero e nomi delle colonne) del risultato di una query non può variare a seconda dei dati selezionati. Una delle possibili soluzioni è creare dinamicamente una vista, la cui struttura è definita dai dati. La funzione di esempio crea una vista basata sulla tabella 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 $$;

Utilizzare la funzione dopo che la tabella è stata modificata (magari in un trigger) e interrogare la vista creata:

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)

Provalo in db<>violino.

Nota che è necessario ricreare una vista (chiamare la funzione) solo dopo che un nuovo nome è stato aggiunto alla tabella (o un nome è stato rimosso da essa). Se l'insieme dei nomi distinti non cambia, puoi interrogare la vista senza ricrearla. Se il set viene modificato frequentemente, la creazione di una vista temporanea sarebbe un'opzione migliore.

Potresti anche essere interessato a Appiattire le coppie chiave/valore aggregate da un campo JSONB?