Tento dotaz vytvoří úplný příkaz DML, který hledáte:
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;
Můžete jej spustit samostatně nebo tento dotaz zabalit do funkce plpgsql a spustit dotaz automaticky pomocí EXECUTE
:
Plná automatizace
Testováno s 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;
Volejte:
SELECT unnest(names) AS name, unnest (sums) AS col_sum
FROM f_get_sums('public', 'somereport');
Vrátí:
name | col_sum
---------------+---------
int_col1 | 6614
other_int_col | 8364
third_int_col | 2720642
Vysvětlete
Obtížnost je definovat RETURN
zadejte pro funkci, zatímco počet a názvy vrácených sloupců se budou lišit. Jeden detail, který trochu pomáhá:chcete pouze integer
sloupce.
Vyřešil jsem to vytvořením pole bigint
(sum(int_col)
vrátí bigint
). Navíc vracím pole názvů sloupců. Oba jsou seřazeny abecedně podle názvu sloupce.
Ve volání funkce jsem tato pole rozdělil pomocí unnest()
dorazíte k zobrazenému pěknému formátu.
Dynamicky vytvářený a prováděný dotaz je pokročilá záležitost. Nenechte se zmást více vrstvami uvozovek. V podstatě máte EXECUTE
který vyžaduje ke spuštění textový argument obsahující dotaz SQL. Tento text zase poskytuje sekundární SQL dotaz, který vytváří řetězec dotazu primárního dotazu.
Pokud je toho příliš mnoho najednou nebo plpgsql
je pro vás poměrně nová, začněte touto související odpovědí
kde vysvětlím základy práce s mnohem jednodušší funkcí a poskytnu odkazy na příručku pro hlavní funkce.
Pokud výkon je zásadní dotazovat se přímo v katalogu Postgres (pg_catalog.pg_attributes
) namísto použití standardizovaného (ale pomalého) information_schema.columns
. Zde je jednoduchý příklad s pg_attributes
.