Obecně si musíte nastudovat základy , než začnete klást otázky.
Přečtěte si vynikající příručku o CREATE FUNCTION
, PL/pgSQL
a funkce SQL
.
Hlavní body, proč je příklad nesmysl
-
Za prvé, nemůžete odevzdat identifikátor jako ty. Identifikátory nelze parametrizovat v prostém SQL. Budete potřebovat dynamické SQL k tomu.
Samozřejmě to podle vašich požadavků ve skutečnosti nepotřebujete. Jedná se pouze o jeden stůl. Je nesmysl zkoušet to parametrizovat. -
Nepoužívejte názvy typů jako identifikátory. Používám
_date
místodate
jako název parametru a přejmenoval sloupec tabulky naasset_date
.ALTER
odpovídající definici vaší tabulky. -
Funkce načítající data z tabulky nemůže být nikdy
IMMUTABLE
. Přečtěte si příručku. -
Mixujete syntaxi SQL s prvky plpgsql nesmyslnými způsoby.
WITH
je součástíSELECT
a nelze je kombinovat s řídicími strukturami plpgsql jakoLOOP
neboIF
.
Správná funkce
Správná funkce může vypadat takto (jeden z mnoha způsobů):
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
Výkon by neměl být tak špatný, ale je to jen zbytečná komplikace.
Správné řešení:prostý dotaz
Nejjednodušší (a pravděpodobně nejrychlejší) způsob by byl s funkcí 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;
Standardní odchylka
Podle vašeho pozdějšího komentáře chcete vypočítat statistická čísla, jako je standardní odchylka.
Existují vyhrazené agregační funkce pro statistiky
v PostgreSQL.