通常、基本を学ぶ必要があります 、質問を始める前に。
CREATE FUNCTION
、 PL / pgSQL
および
例がナンセンスである理由の主なポイント
-
まず、識別子を渡すことはできません あなたのように。プレーンSQLでは識別子をパラメータ化できません。 が必要です。動的SQL
もちろん、要件に応じて、実際には必要ありません。関係するテーブルは1つだけです。それをパラメータ化しようとするのは意味がありません。 -
タイプ名を識別子として使用しないでください。
_date
を使用していますdate
の代わりに パラメータ名として、テーブル列の名前をasset_date
に変更しました 。ALTER
それに応じてテーブル定義。 -
テーブルからデータをフェッチする関数を
IMMUTABLE
にすることはできません。 。 マニュアルをお読みください。 -
SQL構文とplpgsql要素を無意味な方法で混合しています。
WITH
SELECT
の一部です ステートメントであり、LOOP
のようなplpgsql制御構造と混合することはできません またはIF
。
適切な機能
適切な関数は次のようになります(多くの方法の1つ):
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
パフォーマンスはそれほど悪くないはずですが、それは無意味な複雑さです。
適切な解決策:単純なクエリ
最も簡単な(そしておそらく最速の)方法は、ウィンドウ関数<を使用することです。強い>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;
標準偏差
後のコメントによると、標準偏差などの統計数値を計算する必要があります。
専用の