Generelt skal du studere det grundlæggende , før du begynder at stille spørgsmål.
Læs den fremragende manual om CREATE FUNCTION
, PL/pgSQL
og SQL-funktioner
.
Vigtige punkter, hvorfor eksemplet er nonsens
-
For det første kan du ikke aflevere en identifikator ligesom du gør. Identifikatorer kan ikke parametreres i almindelig SQL. Du skal bruge dynamisk SQL for det.
Selvfølgelig har du faktisk ikke brug for det, i henhold til dine krav. Der er kun ét bord involveret. Det er noget nonsens at forsøge at parametrere det. -
Brug ikke typenavne som identifikatorer. Jeg bruger
_date
i stedet fordate
som parameternavn og omdøbte din tabelkolonne tilasset_date
.ALTER
din tabeldefinition i overensstemmelse hermed. -
En funktion, der henter data fra en tabel, kan aldrig være
IMMUTABLE
. Læs manualen. -
Du blander SQL-syntaks med plpgsql-elementer på meningsløse måder.
WITH
er en del af enSELECT
sætning og kan ikke blandes med plpgsql kontrolstrukturer somLOOP
ellerIF
.
Korrekt funktion
En korrekt funktion kunne se sådan ud (en af mange måder):
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
Ydeevnen burde ikke være så dårlig, men det er bare en meningsløs komplikation.
Korrekt løsning:almindelig forespørgsel
Den enkleste (og sandsynligvis hurtigste) måde ville være med vinduesfunktionen 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;
Standardafvigelse
Som i din senere kommentar vil du beregne statistiske tal som standardafvigelse.
Der er dedikerede aggregerede funktioner til statistik
i PostgreSQL.