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

Come eseguire la stessa aggregazione su ogni colonna, senza elencare le colonne?

Hai bisogno di SQL dinamico per questo, il che significa che devi creare una funzione o eseguire un DO comando. Poiché non puoi restituire valori direttamente da quest'ultimo, una funzione plpgsql è:

CREATE OR REPLACE function f_count_all(_tbl text
                           , OUT columns text[], OUT counts bigint[])
  RETURNS record LANGUAGE plpgsql AS
$func$
BEGIN

EXECUTE (
    SELECT 'SELECT
     ARRAY[' || string_agg('''' || quote_ident(attname) || '''', ', ') || '], 
     ARRAY[' || string_agg('count(' || quote_ident(attname) || ')', ', ') || ']
    FROM ' || _tbl
    FROM   pg_attribute
    WHERE  attrelid = _tbl::regclass
    AND    attnum  >= 1           -- exclude tableoid & friends (neg. attnum)
    AND    attisdropped is FALSE  -- exclude deleted columns
    GROUP  BY attrelid
    )
INTO columns, counts;

END
$func$;

Chiama:

SELECT * FROM f_count_all('myschema.mytable');

Resi:

columns       | counts
--------------+--------
{c1, c2, c3,} | {17 1,0}

Ulteriori spiegazioni e collegamenti su SQL dinamico e EXECUTE in questa domanda correlata - o in un altro paio qui su SO, prova questa ricerca.

Molto simile a questa domanda:
postgresql - conteggio (nessun valore nullo) di ogni colonna in una tabella

Potresti anche provare a restituire un tipo di record polimorfico per ottenere colonne singole in modo dinamico, ma è piuttosto complesso e avanzato. Probabilmente troppo sforzo per il tuo caso. Altro in questa risposta correlata.