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

Postgresの動的ベースによる累積加算

    独自の集計関数を作成する 、ウィンドウ関数として使用できます。

    特殊な集計関数

    想像以上に簡単です:

    CREATE OR REPLACE FUNCTION f_sum_cap50 (numeric, numeric)
      RETURNS numeric LANGUAGE sql AS
    'SELECT CASE WHEN $1 > 50 THEN 0 ELSE $1 END + $2';
    
    CREATE AGGREGATE sum_cap50 (numeric) (
      sfunc    = f_sum_cap50
    , stype    = numeric
    , initcond = 0
    );
    

    次に:

    SELECT *, sum_cap50(val) OVER (PARTITION BY fk
                                   ORDER BY created) > 50 AS threshold_met 
    FROM   test
    WHERE  fk = 5;
    

    要求どおりの結果。

    db <> fiddle こちら
    古い sqlfiddle

    一般的な集計関数

    任意のしきい値で機能させるため および任意の(数値)データ型 、および NULLを許可する 値

    CREATE OR REPLACE FUNCTION f_sum_cap (anyelement, anyelement, anyelement)
      RETURNS anyelement
      LANGUAGE sql STRICT AS
    $$SELECT CASE WHEN $1 > $3 THEN '0' ELSE $1 END + $2;$$;
    
    CREATE AGGREGATE sum_cap (anyelement, anyelement) (
      sfunc    = f_sum_cap
    , stype    = anyelement
    , initcond = '0'
    );
    

    次に、任意の数値タイプで、たとえば110の制限で呼び出すには:

    SELECT *
         , sum_cap(val, '110') OVER (PARTITION BY fk
                                     ORDER BY created) AS capped_at_110
         , sum_cap(val, '110') OVER (PARTITION BY fk
                                     ORDER BY created) > 110 AS threshold_met 
    FROM   test
    WHERE  fk = 5;
    

    db <> fiddle こちら
    古い sqlfiddle

    説明

    あなたの場合、 NULLに対して防御する必要はありません val以降の値 NOT NULLが定義されています 。 NULLの場合 関与できる場合は、f_sum_cap()を定義します STRICTとして ドキュメントごと ):

    関数と集計の両方がもう1つの引数を取ります。 polymorphic の場合 バリアントは、ハードコードされたデータ型または先頭の引数と同じポリモーフィック型にすることができます。

    ポリモーフィック関数について:

    型なし文字列リテラルの使用に注意してください 、デフォルトでintegerとなる数値リテラルではありません !




    1. 関数mysql_real_escape_stringに相当するPDOとは何ですか?

    2. .NetアプリケーションからOracleストアドプロシージャに配列を渡す

    3. MySQLInnodbクラッシュ

    4. Laravel5Migrateでタイムゾーンを使用してTimeStampを設定する方法