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

Postgresで動的クエリ+ユーザー定義データ型を使用する

    基本的なUPDATE

    最初のクエリを、このはるかに短く効率的な単一のUPDATEに置き換えます コマンド:

    UPDATE features
    SET   (x1,x2,x3,x4,x5,x6, y)   
        = ((x1 - g.avg1) / g.range1
         , (x2 - g.avg2) / g.range2
     --  , (x3 - ...
         , (y  - g.avgy) / g.rangey)
    FROM (
       SELECT avg(x1) AS avg1, max(x1) - min(x1) AS range1
            , avg(x2) AS avg2, max(x2) - min(x2) AS range2
         -- , avg(x3) ...
            , avg(y) AS avgy, max(y) - min(y) AS rangey
       FROM   features
       ) g;
    

    短いUPDATEについて 構文:

    動的機能

    より単純なクエリに基づいて、任意の数の列の動的関数を次に示します。

    CREATE OR REPLACE FUNCTION scale_function_dyn()
      RETURNS void AS
    $func$
    DECLARE
       cols text;  -- list of target columns
       vals text;  -- list of values to insert
       aggs text;  -- column list for aggregate query
    BEGIN
       SELECT INTO cols, vals, aggs
              string_agg(quote_ident(attname), ', ')
            , string_agg(format('(%I - g.%I) / g.%I'
                              , attname, 'avg_' || attname, 'range_' || attname), ', ')
            , string_agg(format('avg(%1$I) AS %2$I, max(%1$I) - min(%1$I) AS %3$I'
                              , attname, 'avg_' || attname, 'range_' || attname), ', ')
       FROM   pg_attribute
       WHERE  attrelid = 'features'::regclass
       AND    attname NOT IN ('n', 'x0')  -- exclude columns from update
       AND    NOT attisdropped            -- no dropped (dead) columns
       AND    attnum > 0;                 -- no system columns
    
       EXECUTE format('UPDATE features
                       SET   (%s) = (%s)
                       FROM  (SELECT %s FROM features) g'
                     , cols, vals, aggs);
    
    END
    $func$  LANGUAGE plpgsql;
    

    詳細な説明付きの関連回答:

    SQLフィドル。




    1. MySQLは、複数の列を使用して重複するレコードを選択します

    2. PHP / MySQL-一意のランダムな文字列を作成する最良の方法は?

    3. 作成ユーザーの書き方は? MySQLプリペアドステートメントを使用

    4. SQL ServerからC#のbyte []に​​varbinary(MAX)を取得します