Diese Abfrage erstellt die vollständige DML-Anweisung, nach der Sie suchen:
WITH x AS (
SELECT 'public'::text AS _schema -- provide schema name ..
,'somereport'::text AS _tbl -- .. and table name once
)
SELECT 'SELECT ' || string_agg('sum(' || quote_ident(column_name)
|| ') AS sum_' || quote_ident(column_name), ', ')
|| E'\nFROM ' || quote_ident(x._schema) || '.' || quote_ident(x._tbl)
FROM x, information_schema.columns
WHERE table_schema = _schema
AND table_name = _tbl
AND data_type = 'integer'
GROUP BY x._schema, x._tbl;
Sie können sie separat ausführen oder diese Abfrage in eine plpgsql-Funktion packen und die Abfrage automatisch mit EXECUTE
ausführen :
Vollständige Automatisierung
Getestet mit PostgreSQL 9.1.4
CREATE OR REPLACE FUNCTION f_get_sums(_schema text, _tbl text)
RETURNS TABLE(names text[], sums bigint[]) AS
$BODY$
BEGIN
RETURN QUERY EXECUTE (
SELECT 'SELECT ''{'
|| string_agg(quote_ident(c.column_name), ', ' ORDER BY c.column_name)
|| '}''::text[],
ARRAY['
|| string_agg('sum(' || quote_ident(c.column_name) || ')'
, ', ' ORDER BY c.column_name)
|| ']
FROM '
|| quote_ident(_schema) || '.' || quote_ident(_tbl)
FROM information_schema.columns c
WHERE table_schema = _schema
AND table_name = _tbl
AND data_type = 'integer'
);
END;
$BODY$
LANGUAGE plpgsql;
Aufruf:
SELECT unnest(names) AS name, unnest (sums) AS col_sum
FROM f_get_sums('public', 'somereport');
Rückgabe:
name | col_sum
---------------+---------
int_col1 | 6614
other_int_col | 8364
third_int_col | 2720642
Erklären
Die Schwierigkeit besteht darin, den RETURN
zu definieren Typ für die Funktion, während Anzahl und Namen der zurückgegebenen Spalten variieren. Ein Detail, das ein wenig hilft:Sie wollen nur integer
Spalten.
Ich habe das gelöst, indem ich ein Array von bigint
gebildet habe (sum(int_col)
gibt bigint
zurück ). Außerdem gebe ich ein Array von Spaltennamen zurück. Beide alphabetisch nach Spaltennamen sortiert.
Im Funktionsaufruf zerlege ich diese Arrays mit unnest()
Ankommend bei dem ansehnlichen angezeigten Format.
Die dynamisch erstellte und ausgeführte Abfrage ist fortgeschrittenes Zeug. Lassen Sie sich nicht durch mehrere Ebenen von Anführungszeichen verwirren. Grundsätzlich haben Sie EXECUTE
die ein Textargument akzeptiert, das die auszuführende SQL-Abfrage enthält. Dieser Text wiederum wird von einer sekundären SQL-Abfrage bereitgestellt, die die Abfragezeichenfolge der primären Abfrage erstellt.
Wenn das zu viel auf einmal ist oder plpgsql
ziemlich neu für Sie ist, beginnen Sie mit dieser verwandten Antwort
wo ich die Grundlagen erkläre, die sich mit einer viel einfacheren Funktion befassen, und Links zum Handbuch für die Hauptfunktionen bereitstelle.
Wenn Leistung unbedingt den Postgres-Katalog direkt abfragen (pg_catalog.pg_attributes
) anstatt die standardisierten (aber langsamen) information_schema.columns
zu verwenden . Hier ist ein einfaches Beispiel mit pg_attributes
.