Den här frågan skapar den fullständiga DML-satsen du är ute efter:
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;
Du kan köra den separat eller slå in den här frågan i en plpgsql-funktion och köra frågan automatiskt med EXECUTE
:
Full automatisering
Testad med 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;
Ring:
SELECT unnest(names) AS name, unnest (sums) AS col_sum
FROM f_get_sums('public', 'somereport');
Returnerar:
name | col_sum
---------------+---------
int_col1 | 6614
other_int_col | 8364
third_int_col | 2720642
Förklara
Svårigheten är att definiera RETURN
typ för funktionen, medan antal och namn på kolumner som returneras kommer att variera. En detalj som hjälper lite:du vill bara ha integer
kolumner.
Jag löste detta genom att bilda en array av bigint
(sum(int_col)
returnerar bigint
). Dessutom returnerar jag en rad kolumnnamn. Båda sorterade alfabetiskt efter kolumnnamn.
I funktionsanropet delade jag upp dessa arrayer med unnest()
anländer till det stiliga formatet som visas.
Den dynamiskt skapade och körda frågan är avancerade saker. Bli inte förvirrad av flera lager av citat. I grund och botten har du EXECUTE
som kräver ett textargument som innehåller SQL-frågan för att köras. Denna text tillhandahålls i sin tur av sekundär SQL-fråga som bygger frågesträngen för den primära frågan.
Om detta är för mycket på en gång eller plpgsql
är ganska nytt för dig, börja med det här relaterade svaret
där jag förklarar grunderna för en mycket enklare funktion och ger länkar till manualen för de viktigaste funktionerna.
Om prestanda är viktigt att fråga Postgres-katalogen direkt (pg_catalog.pg_attributes
) istället för att använda de standardiserade (men långsamma) information_schema.columns
. Här är ett enkelt exempel med pg_attributes
.