Zasadniczo musisz poznać podstawy , zanim zaczniesz zadawać pytania.
Przeczytaj doskonałą instrukcję o CREATE FUNCTION
, PL/pgSQL
i funkcje SQL
.
Główne punkty, dlaczego przykład jest nonsensem
-
Po pierwsze, nie możesz oddać identyfikatora tak jak ty. Nie można sparametryzować identyfikatorów w zwykłym języku SQL. Potrzebujesz dynamiczny SQL w tym celu.
Oczywiście tak naprawdę nie jest to potrzebne, zgodnie z Twoimi wymaganiami. W grę wchodzi tylko jeden stół. Nie ma sensu próbować go sparametryzować. -
Nie używaj nazw typów jako identyfikatorów. Używam
_date
zamiastdate
jako nazwę parametru i zmieniono nazwę kolumny tabeli naasset_date
.ALTER
zgodnie z definicją tabeli. -
Funkcja pobierająca dane z tabeli nigdy nie może być
IMMUTABLE
. Przeczytaj instrukcję. -
Mieszasz składnię SQL z elementami plpgsql w bezsensowny sposób.
WITH
jest częściąSELECT
instrukcja i nie może być mieszana ze strukturami kontrolnymi plpgsql, takimi jakLOOP
lubIF
.
Właściwe działanie
Właściwa funkcja może wyglądać tak (jeden z wielu sposobów):
CREATE FUNCTION percentage_change_func(_asset_symbol text)
RETURNS TABLE(asset_date date, price numeric, pct_change numeric) AS
$func$
DECLARE
last_price numeric;
BEGIN
FOR asset_date, price IN
SELECT a.asset_date, a.price
FROM asset_histories a
WHERE a.asset_symbol = _asset_symbol
ORDER BY a.asset_date -- traverse ascending
LOOP
pct_change := price / last_price; -- NULL if last_price is NULL
RETURN NEXT;
last_price := price;
END LOOP;
END
$func$ LANGUAGE plpgsql STABLE
Wydajność nie powinna być taka zła, ale to tylko bezsensowna komplikacja.
Właściwe rozwiązanie:zwykłe zapytanie
Najprostszym (i prawdopodobnie najszybszym) sposobem byłoby użycie funkcji okna lag()
:
SELECT asset_date, price
,price / lag(price) OVER (ORDER BY asset_date) AS pct_change
FROM asset_histories
WHERE asset_symbol = _asset_symbol
ORDER BY asset_date;
Odchylenie standardowe
Zgodnie z Twoim późniejszym komentarzem, chcesz obliczyć liczby statystyczne, takie jak odchylenie standardowe.
Istnieją dedykowane funkcje agregujące dla statystyk
w PostgreSQL.