Statistika systému
Než vrhnete svůj vlastní, podívejte se na systémovou tabulku pg_statistic
nebo zobrazení pg_stats
:
Může již obsahovat některé statistiky, které se chystáte vypočítat. Je vyplněna ANALYZE
, takže to můžete před kontrolou spustit pro nové (nebo jakékoli) tabulky.
-- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
Obecná dynamická funkce plpgsql
Chcete vrátit minimální hodnotu pro každý sloupec v dané tabulce . Toto není triviální úkol, protože funkce (jako SQL obecně) vyžaduje znát návratový typ v době vytvoření – nebo alespoň v době volání pomocí polymorfních datových typů.
Tato funkce dělá vše automaticky a bezpečně. Funguje pro jakékoli tabulka, pokud agregační funkce min()
je povoleno pro každý sloupec. Ale potřebujete abyste se vyznali v 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$;
Zavolejte (důležité!):
SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
db<>fiddle zde
Staré sqlfiddle
Musíte pochopit tyto pojmy:
- Dynamické SQL v plpgsql s příkazem
EXECUTE
- Polymorfní typy
- Typy řádků a tabulky v Postgres
- Jak se bránit proti SQL injection
- Agregační funkce
- Systémové katalogy
Související odpověď s podrobným vysvětlením:
- Název tabulky jako Parametr funkce PostgreSQL
- Refaktorujte funkci PL/pgSQL tak, aby vrátila výstup různých SELECT dotazů
- Přenos datového typu Postgres
- Jak nastavit hodnotu pole složené proměnné pomocí dynamického SQL
- Jak zkontrolovat, zda tabulka v daném schématu existuje
- Vybrat sloupce s konkrétními názvy sloupců v PostgreSQL
- Vygenerujte řadu dat – jako vstup použijte typ data
Zvláštní potíže s neshodou typu
Využívám toho, že Postgres definuje typ řádku pro každou existující tabulku. Pomocí konceptu polymorfních typů jsem schopen vytvořit jeden funkce, která funguje pro jakoukoli tabulku.
Některé agregační funkce však vracejí související, ale odlišné datové typy ve srovnání s podkladovým sloupcem. Například min(varchar_column)
vrátí text
, který je bitově kompatibilní, ale ne přesně stejný datový typ. Funkce PL/pgSQL zde mají slabé místo a trvají na datových typech přesně jak je uvedeno v RETURNS
doložka. Žádný pokus o obsazení, dokonce ani implicitní obsazení, nemluvě o obsazení úkolu.
To by se mělo zlepšit. Testováno s Postgres 9.3. Netestoval jsem znovu s 9.4, ale jsem si docela jistý, že se v této oblasti nic nezměnilo.
To je místo, kde tato konstrukce přichází jako řešení :
SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
Přetypováním celého řádku na typ řádku podkladové tabulky explicitně vynutíme přetypování přiřazení, aby získalo původní datové typy pro každý sloupec.
To může selhat pro některé agregační funkce. sum()
vrátí numeric
pro sum(bigint_column)
aby se přizpůsobil sumě přesahující základní datový typ. Odesílání zpět do bigint
může selhat ...