PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como realizar a mesma agregação em todas as colunas, sem listar as colunas?


Você precisa de SQL dinâmico para isso, o que significa que você precisa criar uma função ou executar um DO comando. Como você não pode retornar valores diretamente do último, uma função plpgsql isto é:
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$;

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

Devoluções:
columns       | counts
--------------+--------
{c1, c2, c3,} | {17 1,0}

Mais explicações e links sobre SQL dinâmico e EXECUTE nesta questão relacionada - ou mais algumas aqui no SO, tente esta pesquisa.

Muito semelhante a esta pergunta:
postgresql - contagem (sem valores nulos) de cada coluna em uma tabela

Você pode até tentar retornar um tipo de registro polimórfico para obter colunas únicas dinamicamente, mas isso é bastante complexo e avançado. Provavelmente muito esforço para o seu caso. Mais nesta resposta relacionada.