In genere è necessario studiare le basi , prima di iniziare a fare domande.
Leggi l'eccellente manuale su CREATE FUNCTION
, PL/pgSQL
e Funzioni SQL
.
Principali punti per cui l'esempio non ha senso
-
Innanzitutto, non puoi consegnare un identificatore come fai tu. Gli identificatori non possono essere parametrizzati in SQL semplice. Avresti bisogno di SQL dinamico per quello.
Ovviamente, in realtà non ne hai bisogno, in base alle tue esigenze. C'è solo una tabella coinvolta. Non ha senso provare a parametrizzarlo. -
Non utilizzare i nomi dei tipi come identificatori. Uso
_date
invece didate
come nome del parametro e rinominato la colonna della tabella inasset_date
.ALTER
la definizione della tua tabella di conseguenza. -
Una funzione che recupera i dati da una tabella non può mai essere
IMMUTABLE
. Leggi il manuale. -
Stai mescolando la sintassi SQL con elementi plpgsql in modi senza senso.
WITH
fa parte di unSELECT
istruzione e non può essere mescolato con strutture di controllo plpgsql comeLOOP
oIF
.
Funzione corretta
Una funzione corretta potrebbe assomigliare a questa (uno dei tanti modi):
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
Le prestazioni non dovrebbero essere così male, ma è solo una complicazione inutile.
Soluzione corretta:query semplice
Il modo più semplice (e probabilmente più veloce) sarebbe con la funzione finestra 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;
Deviazione standard
Secondo il tuo commento successivo, vuoi calcolare numeri statistici come la deviazione standard.
Ci sono aggrega le funzioni per le statistiche
in PostgreSQL.