Im Allgemeinen müssen Sie die Grundlagen lernen , bevor Sie anfangen, Fragen zu stellen.
Lesen Sie das exzellente Handbuch zu CREATE FUNCTION
, PL/pgSQL
und SQL-Funktionen
.
Wichtige Punkte, warum das Beispiel Unsinn ist
-
Erstens können Sie keine Kennung abgeben so wie du es tust. Bezeichner können in einfachem SQL nicht parametrisiert werden. Sie benötigen dynamisches SQL dafür.
Natürlich brauchen Sie das nach Ihren Anforderungen eigentlich nicht. Es ist nur eine Tabelle beteiligt. Es ist Unsinn zu versuchen und es zu parametrisieren. -
Verwenden Sie keine Typnamen als Bezeichner. Ich verwende
_date
stattdate
als Parametername und benannte Ihre Tabellenspalte inasset_date
um .ALTER
Ihre Tabellendefinition entsprechend. -
Eine Funktion, die Daten aus einer Tabelle holt, kann niemals
IMMUTABLE
sein . Lesen Sie das Handbuch. -
Sie mischen SQL-Syntax mit plpgsql-Elementen auf unsinnige Weise.
WITH
ist Teil einesSELECT
-Anweisung und kann nicht mit plpgsql-Kontrollstrukturen wieLOOP
gemischt werden oderIF
.
Einwandfreie Funktion
Eine richtige Funktion könnte so aussehen (eine von vielen Möglichkeiten):
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
Die Leistung sollte nicht so schlecht sein, aber es ist nur eine sinnlose Komplikation.
Richtige Lösung:einfache Abfrage
Der einfachste (und wahrscheinlich schnellste) Weg wäre mit der Fensterfunktion 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;
Standardabweichung
Gemäß Ihrem späteren Kommentar möchten Sie statistische Zahlen wie die Standardabweichung berechnen.
Es gibt spezielle Aggregatfunktionen für Statistiken
in PostgreSQL.