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.