3

Postgresで次のことを行うことは可能ですか?

SELECT column_name FROM information_schema WHERE table_name = 'somereport' AND data_type = 'integer';

SELECT SUM(coulmn_name[0]),SUM(coulmn_name[1]) ,SUM(coulmn_name[3]) FROM somereport;

つまり、特定の基準に応じてテーブルから列のグループを選択し、テーブル内のそれらの各列を合計する必要があります。

これをループで実行できることはわかっているので、各列を個別にカウントできますが、明らかに、情報スキーマクエリから返される各列のクエリが必要です。例えば:

FOR r IN select column_name from information_schema where report_view_name = 'somereport' and data_type = 'integer';
LOOP
    SELECT SUM(r.column_name) FROM somereport;
END
4

1 に答える 1

4

このクエリは、必要な完全な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少し役立つ1つの詳細:列のみが必要です。

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

関数呼び出しで、これらの配列を分割してunnest()、表示されたハンサムな形式に到達しました。

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

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

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

于 2012-08-20T00:47:58.147 に答える