Systemstatistiken
Bevor Sie Ihre eigene erstellen, werfen Sie einen Blick auf die Systemtabelle pg_statistic
oder die Ansicht pg_stats
:
Möglicherweise enthält es bereits einige der Statistiken, die Sie berechnen möchten. Es wird von ANALYZE
ausgefüllt , also könnten Sie das vor der Überprüfung für neue (oder beliebige) Tabellen ausführen.
-- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
Generische dynamische plpgsql-Funktion
Sie möchten den Mindestwert für jede Spalte in einer bestimmten Tabelle zurückgeben . Dies ist keine triviale Aufgabe, da eine Funktion (wie SQL im Allgemeinen) den Rückgabetyp zum Zeitpunkt der Erstellung kennen muss - oder zumindest zum Zeitpunkt des Aufrufs mit Hilfe polymorpher Datentypen.
Diese Funktion erledigt alles automatisch und sicher. Funktioniert für alle Tabelle, solange die Aggregatfunktion min()
ist für jede Spalte erlaubt. Aber Sie brauchen um sich mit PL/pgSQL vertraut zu machen.
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$;
Rufen Sie an (wichtig!):
SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
db<>fiddle hier
Alter sqlfiddle
Sie müssen diese Konzepte verstehen:
- Dynamisches SQL in plpgsql mit
EXECUTE
- Polymorphe Typen
- Zeilentypen und Tabellentypen in Postgres
- Wie man sich gegen SQL-Injection verteidigt
- Aggregatfunktionen
- Systemkataloge
Verwandte Antwort mit ausführlicher Erklärung:
- Tabellenname als PostgreSQL-Funktionsparameter
- Refaktorisieren Sie eine PL/pgSQL-Funktion, um die Ausgabe verschiedener SELECT-Abfragen zurückzugeben
- Umwandlung des Postgres-Datentyps
- So setzen Sie den Wert eines zusammengesetzten Variablenfelds mit dynamischem SQL
- Überprüfen, ob eine Tabelle in einem bestimmten Schema vorhanden ist
- Spalten auswählen mit bestimmten Spaltennamen in PostgreSQL
- Datumsreihe generieren - Datumstyp als Eingabe verwenden
Besondere Schwierigkeit bei Typenkonflikten
Ich nutze Postgres, um einen Zeilentyp für jede vorhandene Tabelle zu definieren. Mit dem Konzept der polymorphen Typen kann ich einen erstellen Funktion, die für jede Tabelle funktioniert.
Einige Aggregatfunktionen geben jedoch verwandte, aber unterschiedliche Datentypen im Vergleich zur zugrunde liegenden Spalte zurück. Beispiel:min(varchar_column)
gibt text
zurück , die bitkompatibel ist, aber nicht genau gleichen Datentyp. PL/pgSQL-Funktionen haben hier eine Schwachstelle und bestehen genau auf Datentypen wie in den RETURNS
angegeben Klausel. Kein Versuch zu casten, nicht einmal implizite Casts, ganz zu schweigen von Zuordnungscasts.
Das sollte verbessert werden. Getestet mit Postgres 9.3. Habe es mit 9.4 nicht erneut getestet, aber ich bin mir ziemlich sicher, dass sich in diesem Bereich nichts geändert hat.
Hier kommt dieses Konstrukt als Workaround ins Spiel :
SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
Indem wir die gesamte Zeile explizit in den Zeilentyp der zugrunde liegenden Tabelle umwandeln, erzwingen wir Zuweisungsumwandlungen, um die ursprünglichen Datentypen für jede Spalte zu erhalten.
Dies kann für einige Aggregatfunktionen fehlschlagen. sum()
gibt numeric
zurück für eine sum(bigint_column)
um eine Summe aufzunehmen, die den Basisdatentyp überschreitet. Casting zurück zu bigint
kann fehlschlagen ...