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

テーブルから動的な列のセットを選択し、それぞれの合計を取得します

    このクエリは、必要な完全なDMLステートメントを作成します。

    WITH x AS (
       SELECT 'public'::text     AS _schema  -- provide schema name ..
             ,'somereport'::text AS _tbl     -- .. and table name once
       )
    SELECT 'SELECT ' || string_agg('sum(' || quote_ident(column_name)
                     || ') AS sum_' || quote_ident(column_name), ', ')
           || E'\nFROM   ' || quote_ident(x._schema) || '.' || quote_ident(x._tbl)
    FROM   x, information_schema.columns
    WHERE  table_schema = _schema
    AND    table_name = _tbl
    AND    data_type = 'integer'
    GROUP  BY x._schema, x._tbl;
    

    個別に実行することも、このクエリをplpgsql関数でラップして、EXECUTEを使用してクエリを自動的に実行することもできます。 :

    完全自動化

    PostgreSQL9.1.4でテスト済み

    CREATE OR REPLACE FUNCTION f_get_sums(_schema text, _tbl text)
      RETURNS TABLE(names text[], sums bigint[]) AS
    $BODY$
    BEGIN
    
    RETURN QUERY EXECUTE (
        SELECT 'SELECT ''{'
               || string_agg(quote_ident(c.column_name), ', ' ORDER BY c.column_name)
               || '}''::text[],
               ARRAY['
               || string_agg('sum(' || quote_ident(c.column_name) || ')'
                                                       , ', ' ORDER BY c.column_name)
               || ']
        FROM   '
               || quote_ident(_schema) || '.' || quote_ident(_tbl)
        FROM   information_schema.columns c
        WHERE  table_schema = _schema
        AND    table_name = _tbl
        AND    data_type = 'integer'
        );
    
    END;
    $BODY$
      LANGUAGE plpgsql;
    

    電話:

    SELECT unnest(names) AS name, unnest (sums) AS col_sum
    FROM   f_get_sums('public', 'somereport');
    

    返品:

       name        | col_sum
    ---------------+---------
     int_col1      |    6614
     other_int_col |    8364
     third_int_col | 2720642
    

    説明

    難しいのは、RETURNを定義することです。 関数のタイプ。返される列の数と名前は異なります。少し役立つ詳細:integerだけが必要です 列。

    bigintの配列を作成することでこれを解決しました (sum(int_col) bigintを返します )。さらに、列名の配列を返します。どちらも列名のアルファベット順に並べ替えられています。

    関数呼び出しでは、これらの配列を unnest() 表示されたハンサムなフォーマットに到達します。

    動的に作成および実行されるクエリは高度なものです。引用符の複数のレイヤーに混乱しないでください。基本的にあなたはEXECUTEを持っています これは、実行するSQLクエリを含むテキスト引数を取ります。このテキストは、プライマリクエリのクエリ文字列を作成するセカンダリSQLクエリによって提供されます。

    これが一度に多すぎる場合、またはplpgsql かなり新しいので、この関連する回答 から始めてください ここでは、はるかに単純な機能を扱う基本を説明し、主要な機能のマニュアルへのリンクを提供します。

    パフォーマンスの場合 Postgresカタログを直接クエリすることが不可欠です(pg_catalog.pg_attributes )標準化された(ただし遅い)information_schema.columnsを使用する代わりに 。これは、 pg_attributesを使用した簡単な例です。




    1. アクセス互換のWideWorldImportersSQLServerデータベース

    2. docker-compose mysqlコンテナに接続するとアクセスが拒否されますが、同じイメージを実行しているdockerはアクセスを拒否しません

    3. Oracle同じトランザクション中に更新されたレコードにアクセスする

    4. SQLServerの命名規則に関する感情に訴えない論理的考察