Over het algemeen moet je de basis bestuderen , voordat je vragen gaat stellen.
Lees de uitstekende handleiding over CREATE FUNCTION
, PL/pgSQL
en SQL-functies
.
Belangrijkste punten waarom het voorbeeld onzin is
-
Ten eerste mag je geen identifier . inleveren zoals jij doet. Identifiers kunnen niet worden geparametriseerd in gewone SQL. Je hebt nodig dynamische SQL daarvoor.
Natuurlijk heb je dat niet echt nodig, volgens jouw eisen. Er is maar één tafel bij betrokken. Het is onzin om het te proberen te parametriseren. -
Gebruik geen typenamen als identifiers. Ik gebruik
_date
in plaats vandate
als parameternaam en hernoemde uw tabelkolom naarasset_date
.ALTER
uw tabeldefinitie dienovereenkomstig. -
Een functie die gegevens uit een tabel haalt, kan nooit
IMMUTABLE
zijn . Lees de handleiding. -
U vermengt de SQL-syntaxis met plpgsql-elementen op onzinnige manieren.
WITH
maakt deel uit van eenSELECT
statement en kan niet worden gemengd met plpgsql-besturingsstructuren zoalsLOOP
ofIF
.
Juiste functie
Een goede functie kan er als volgt uitzien (een van de vele manieren):
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
Prestaties zouden niet zo slecht moeten zijn, maar het is gewoon een zinloze complicatie.
Goede oplossing:gewone vraag
De eenvoudigste (en waarschijnlijk snelste) manier zou zijn met de vensterfunctie 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;
Standaarddeviatie
Volgens je latere opmerking wil je statistische getallen zoals standaarddeviatie berekenen.
Er zijn speciale aggregeer functies voor statistieken
in PostgreSQL.