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

全自动化

用 PostgreSQL 9.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列。

我通过形成一个bigintsum(int_col)返回bigint)数组来解决这个问题。此外,我返回一个列名数组。两者都按列名的字母顺序排序。

在函数调用中,我将这些数组拆分unnest()为显示的漂亮格式。

动态创建和执行的查询是高级的东西。不要被多层引号弄糊涂。基本上你有EXECUTE一个包含要执行的 SQL 查询的文本参数。反过来,此文本由构建主查询的查询字符串的辅助 SQL 查询提供。

如果这一次太多或者plpgsql对您来说相当新,请从这个相关答案开始,我解释处理一个更简单的功能的基础知识,并提供主要功能手册的链接。

如果性能很重要,请直接查询 Postgres 目录(pg_catalog.pg_attributes)而不是使用标准化的(但速度慢)information_schema.columns。这是一个简单的例子pg_attributes

于 2012-08-20T00:47:58.147 回答