PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment effectuer la même agrégation sur chaque colonne, sans lister les colonnes ?

Vous avez besoin de SQL dynamique pour cela, ce qui signifie que vous devez créer une fonction ou exécuter un DO commande. Comme vous ne pouvez pas retourner les valeurs directement de ce dernier, une fonction plpgsql c'est :

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$;

Appel :

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

Renvoie :

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

Plus d'explications et de liens sur SQL dynamique et EXECUTE dans cette question connexe - ou quelques autres ici sur SO, essayez cette recherche.

Très similaire à cette question :
postgresql - nombre (pas de valeurs nulles) de chaque colonne dans une table

Vous pouvez même essayer de renvoyer un type d'enregistrement polymorphe pour obtenir dynamiquement des colonnes uniques, mais c'est plutôt complexe et avancé. Probablement trop d'efforts pour votre cas. Plus dans cette réponse connexe.