Statystyki systemu
Zanim wyrzucisz własną, spójrz na tabelę systemową pg_statistic
lub widok pg_stats
:
Może już zawierać niektóre statystyki, które zamierzasz obliczyć. Jest wypełniany przez ANALYZE
, więc możesz uruchomić to dla nowych (lub dowolnych) tabel przed sprawdzeniem.
-- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
Ogólna dynamiczna funkcja plpgsql
Chcesz zwrócić wartość minimalną dla każdej kolumny w danej tabeli . Nie jest to trywialne zadanie, ponieważ funkcja (jak ogólnie SQL) wymaga znajomości typu zwracanego w czasie tworzenia - lub przynajmniej w czasie wywołania za pomocą polimorficznych typów danych.
Ta funkcja robi wszystko automatycznie i bezpiecznie. Działa dla każdego tabeli, o ile funkcja agregująca min()
jest dozwolony dla każdej kolumny. Ale potrzebujesz poznać 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$;
Zadzwoń (ważne!):
SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
db<>fiddle tutaj
Stary sqlfiddle
Musisz zrozumieć te pojęcia:
- Dynamiczny SQL w plpgsql z
EXECUTE
- Typy polimorficzne
- Typy wierszy i typy tabel w Postgresie
- Jak bronić się przed wstrzyknięciem SQL
- Funkcje agregujące
- Katalogi systemowe
Powiązana odpowiedź ze szczegółowym wyjaśnieniem:
- Nazwa tabeli jako Parametr funkcji PostgreSQL
- Refaktoryzuj funkcję PL/pgSQL, aby zwrócić dane wyjściowe różnych zapytań SELECT
- Przesyłanie typu danych Postgres
- Jak ustawić wartość pola zmiennej złożonej za pomocą dynamicznego SQL
- Jak sprawdzić, czy tabela istnieje w danym schemacie
- Wybierz kolumny z określonymi nazwami kolumn w PostgreSQL
- Generuj serie dat — używając typu daty jako danych wejściowych
Specjalny poziom trudności z niezgodnością typów
Korzystam z możliwości Postgresa definiującego typ wiersza dla każdej istniejącej tabeli. Korzystając z koncepcji typów polimorficznych, jestem w stanie stworzyć jeden funkcja, która działa dla każdej tabeli.
Jednak niektóre funkcje agregujące zwracają powiązane, ale różne typy danych w porównaniu z kolumną bazową. Na przykład min(varchar_column)
zwraca text
, który jest zgodny z bitami, ale nie dokładnie ten sam typ danych. Funkcje PL/pgSQL mają tutaj słaby punkt i nalegają na typy danych dokładnie zgodnie z deklaracją w RETURNS
klauzula. Żadnych prób rzutowania, nawet ukrytych rzutów, nie mówiąc już o rzutach przypisania.
To powinno zostać poprawione. Testowane z Postgresem 9.3. Nie testowałem ponownie z wersją 9.4, ale jestem prawie pewien, że w tym obszarze nic się nie zmieniło.
Właśnie tam pojawia się ta konstrukcja jako obejście :
SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
Rzutując cały wiersz na typ wiersza tabeli bazowej, wymuszamy rzutowanie przypisania, aby uzyskać oryginalne typy danych dla każdej kolumny.
Może to zakończyć się niepowodzeniem w przypadku niektórych funkcji agregujących. sum()
zwraca numeric
dla sum(bigint_column)
aby pomieścić sumę przepełniającą podstawowy typ danych. Przesyłanie z powrotem do bigint
może się nie udać ...