sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLレコードを反復処理します。次の行からデータを参照する方法は?

    通常、基本を学ぶ必要があります 、質問を始める前に。
    CREATE FUNCTION PL / pgSQL およびSQL関数

    例がナンセンスである理由の主なポイント

    • まず、識別子を渡すことはできません あなたのように。プレーン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;
    

    標準偏差

    後のコメントによると、標準偏差などの統計数値を計算する必要があります。
    専用の統計の集計関数 PostgreSQLで。



    1. ユーザーのデフォルトデータベースを開くことができません。ログインに失敗しました。 SQL Server ManagementStudioExpressをインストールした後

    2. Oracleデータベースの主キーの自動インクリメント

    3. MySQLに`connectby`の代替手段はありますか?

    4. PhP Mysqlの使用方法は適切にインクルードし、ヘッダーエラーを回避します