Estadísticas del sistema
Antes de lanzar el suyo, eche un vistazo a la tabla del sistema pg_statistic
o la vista pg_stats
:
Es posible que ya tenga algunas de las estadísticas que está a punto de calcular. Está poblado por ANALYZE
, por lo que puede ejecutar eso para tablas nuevas (o cualquier) antes de verificar.
-- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
Función plpgsql dinámica genérica
Quiere devolver el valor mínimo para cada columna en una tabla determinada . Esta no es una tarea trivial, porque una función (como SQL en general) exige conocer el tipo de devolución en el momento de la creación, o al menos en el momento de la llamada con la ayuda de tipos de datos polimórficos.
Esta función hace todo de forma automática y segura. Funciona para cualquier tabla, siempre que la función agregada min()
está permitido para cada columna. Pero necesitas para familiarizarse con 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$;
Llame (¡importante!):
SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
db<>fiddle aquí
Antiguo sqlfiddle
Necesita comprender estos conceptos:
- SQL dinámico en plpgsql con
EXECUTE
- Tipos polimórficos
- Tipos de filas y tipos de tablas en Postgres
- Cómo defenderse de la inyección SQL
- Funciones agregadas
- Catálogos del sistema
Respuesta relacionada con explicación detallada:
- Nombre de tabla como Parámetro de función de PostgreSQL
- Refactorizar una función PL/pgSQL para devolver el resultado de varias consultas SELECT
- Transmisión de tipos de datos de Postgres
- Cómo establecer el valor del campo variable compuesto usando SQL dinámico
- Cómo comprobar si existe una tabla en un esquema dado
- Seleccionar columnas con nombres de columnas particulares en PostgreSQL
- Generar series de fechas - usando el tipo de fecha como entrada
Dificultad especial con tipo de desajuste
Estoy aprovechando que Postgres define un tipo de fila para cada tabla existente. Usando el concepto de tipos polimórficos puedo crear uno función que funciona para cualquier tabla.
Sin embargo, algunas funciones agregadas devuelven tipos de datos relacionados pero diferentes en comparación con la columna subyacente. Por ejemplo, min(varchar_column)
devuelve text
, que es compatible con bits, pero no exactamente el mismo tipo de datos. Las funciones PL/pgSQL tienen un punto débil aquí e insisten en los tipos de datos exactamente como se declara en RETURNS
cláusula. Ningún intento de lanzar, ni siquiera lanzamientos implícitos, por no hablar de lanzamientos de asignación.
Eso debería mejorarse. Probado con Postgres 9.3. No volví a probar con 9.4, pero estoy bastante seguro de que nada ha cambiado en esta área.
Ahí es donde entra esta construcción como solución alternativa :
SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
Al convertir toda la fila al tipo de fila de la tabla subyacente de forma explícita, forzamos las conversiones de asignación para obtener tipos de datos originales para cada columna.
Esto podría fallar para alguna función agregada. sum()
devuelve numeric
para una sum(bigint_column)
para acomodar una suma que desborda el tipo de datos base. Volviendo a bigint
podría fallar...