Estatísticas do sistema
Antes de lançar o seu, dê uma olhada na tabela do sistema
pg_statistic
ou a visualização pg_stats
:Ele já pode ter algumas das estatísticas que você está prestes a calcular. É preenchido por
ANALYZE
, então você pode executar isso para novas (ou quaisquer) tabelas antes de verificar. -- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
Função plpgsql dinâmica genérica
Você deseja retornar o valor mínimo para cada coluna em uma determinada tabela . Esta não é uma tarefa trivial, porque uma função (como SQL em geral) exige saber o tipo de retorno no momento da criação - ou pelo menos no momento da chamada com a ajuda de tipos de dados polimórficos.
Esta função faz tudo de forma automática e segura. Funciona para qualquer tabela, desde que a função agregada
min()
é permitido para cada coluna. Mas você precisa para conhecer o PL/pgSQL. CREATE OR REPLACE FUNCTION f_min_of(_tbl anyelement)
RETURNS SETOF anyelement
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE (
SELECT format('SELECT (t::%2$s).* FROM (SELECT min(%1$s) FROM %2$s) t'
, string_agg(quote_ident(attname), '), min(' ORDER BY attnum)
, pg_typeof(_tbl)::text)
FROM pg_attribute
WHERE attrelid = pg_typeof(_tbl)::text::regclass
AND NOT attisdropped -- no dropped (dead) columns
AND attnum > 0 -- no system columns
);
END
$func$;
Ligue (importante!):
SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
db<>fiddle aqui
Antigo sqlfiddle
Você precisa entender esses conceitos:
- SQL dinâmico em plpgsql com
EXECUTE
- Tipos polimórficos
- Tipos de linha e tipos de tabela no Postgres
- Como se defender contra injeção de SQL
- Funções agregadas
- Catálogos do sistema
Resposta relacionada com explicação detalhada:
- Nome da tabela como Parâmetro de função do PostgreSQL
- Refatorar uma função PL/pgSQL para retornar a saída de várias consultas SELECT
- Conversão de tipo de dados Postgres
- Como definir o valor do campo de variável composta usando SQL dinâmico
- Como verificar se existe uma tabela em um determinado esquema
- Selecionar colunas com nomes de colunas particulares no PostgreSQL
- Gere séries de datas - usando o tipo de data como entrada
Dificuldade especial com incompatibilidade de tipo
Estou aproveitando o Postgres definindo um tipo de linha para cada tabela existente. Usando o conceito de tipos polimórficos eu sou capaz de criar um função que funciona para qualquer tabela.
No entanto, algumas funções agregadas retornam tipos de dados relacionados, mas diferentes, em comparação com a coluna subjacente. Por exemplo,
min(varchar_column)
retorna text
, que é compatível com bits, mas não exatamente o mesmo tipo de dados. As funções PL/pgSQL têm um ponto fraco aqui e insistem em tipos de dados exatamente conforme declarado no RETURNS
cláusula. Nenhuma tentativa de cast, nem mesmo casts implícitos, para não falar de casts de atribuição. Isso deve ser melhorado. Testado com Postgres 9.3. Não testei novamente com 9.4, mas tenho certeza que nada mudou nessa área.
É aí que essa construção entra como solução alternativa :
SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
Ao converter a linha inteira para o tipo de linha da tabela subjacente explicitamente, forçamos as conversões de atribuição para obter os tipos de dados originais para cada coluna.
Isso pode falhar para alguma função agregada.
sum()
retorna numeric
para uma sum(bigint_column)
para acomodar uma soma que estoura o tipo de dados base. Transmitindo de volta para bigint
pode falhar...