sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo realizar la misma agregación en cada columna, sin enumerar las columnas?

Necesita SQL dinámico para eso, lo que significa que tienes que crear una función o ejecutar un DO dominio. Dado que no puede devolver valores directamente desde este último, una función plpgsql es:

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

Llamar:

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

Devoluciones:

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

Más explicaciones y enlaces sobre SQL dinámico y EXECUTE en esta pregunta relacionada, o un par más aquí en SO, pruebe esta búsqueda.

Muy similar a esta pregunta:
postgresql - cuenta (sin valores nulos) de cada columna en una tabla

Incluso podría intentar devolver un tipo de registro polimórfico para obtener columnas individuales dinámicamente, pero eso es bastante complejo y avanzado. Probablemente demasiado esfuerzo para su caso. Más en esta respuesta relacionada.