Systeemstatistieken
Bekijk voordat je je eigen rol gaat de systeemtabel pg_statistic
of de weergave pg_stats
:
Het kan al enkele van de statistieken bevatten die u gaat berekenen. Het wordt ingevuld door ANALYZE
, dus u kunt dat voor nieuwe (of andere) tabellen uitvoeren voordat u het controleert.
-- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
Algemene dynamische plpgsql-functie
U wilt de minimumwaarde voor elke kolom in een bepaalde tabel . Dit is geen triviale taak, omdat een functie (zoals SQL in het algemeen) vraagt om het retourtype te weten tijdens de aanmaaktijd - of in ieder geval tijdens het aanroepen met behulp van polymorfe gegevenstypen.
Deze functie doet alles automatisch en veilig. Werkt voor elke tabel, zolang de aggregatiefunctie min()
is toegestaan voor elke kolom. Maar je nodig om je weg te vinden in 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$;
Bel (belangrijk!):
SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
db<>fiddle hier
Oude sqlfiddle
U moet deze concepten begrijpen:
- Dynamische SQL in plpgsql met
EXECUTE
- Polymorfe typen
- Rijtypen en tabeltypen in Postgres
- Hoe te verdedigen tegen SQL-injectie
- Totale functies
- Systeemcatalogi
Gerelateerd antwoord met gedetailleerde uitleg:
- Tabelnaam als een PostgreSQL-functieparameter
- Refactor een PL/pgSQL-functie om de uitvoer van verschillende SELECT-query's te retourneren
- Gegoten Postgres-gegevenstype
- Hoe de waarde van het samengestelde variabele veld in te stellen met behulp van dynamische SQL
- Hoe te controleren of een tabel in een bepaald schema bestaat
- Selecteer kolommen met bepaalde kolomnamen in PostgreSQL
- Genereer een reeks datums - gebruik het datumtype als invoer
Speciale moeilijkheid met niet-overeenkomende typen
Ik maak gebruik van Postgres die een rijtype definieert voor elke bestaande tabel. Met behulp van het concept van polymorfe typen kan ik één . maken functie die voor elke tafel werkt.
Sommige statistische functies retourneren echter gerelateerde maar verschillende gegevenstypen in vergelijking met de onderliggende kolom. Bijvoorbeeld, min(varchar_column)
retourneert text
, die bit-compatibel is, maar niet precies hetzelfde gegevenstype. PL/pgSQL-functies hebben hier een zwakke plek en staan exact op datatypes zoals aangegeven in de RETURNS
clausule. Geen poging tot casten, zelfs geen impliciete casts, om nog maar te zwijgen van opdrachtcasts.
Dat zou verbeterd moeten worden. Getest met Postgres 9.3. Ik heb niet opnieuw getest met 9.4, maar ik ben er vrij zeker van dat er op dit gebied niets is veranderd.
Dat is waar deze constructie binnenkomt als oplossing :
SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
Door de hele rij expliciet naar het rijtype van de onderliggende tabel te casten, dwingen we toewijzingscasts om originele gegevenstypen voor elke kolom te krijgen.
Dit kan mislukken voor een bepaalde aggregatiefunctie. sum()
retourneert numeric
voor een sum(bigint_column)
om tegemoet te komen aan een som die het basisgegevenstype overschrijdt. Terug casten naar bigint
kan mislukken ...