2016-08-23 51 views
0

我有一个格式化的表格:计算跨多个列的值的总和中的表中的Postgres(PLPGSQL)

fcst_month | idx1 | idx2 | idx3 | val1 | val2 | ... | valN 

我想获得所有的“VAL的之和为每个fcst_month。这似乎是一个很好的方法,这将是使用tablefunc crosstab()(https://www.postgresql.org/docs/9.3/static/tablefunc.html)转置我的表,然后传递给我特定的fcst_month列,但阅读文档和其他例子,所以我不是真的了解如何使用此功能来实现我的目标。

有人能给我一个crosstab()的例子来实现这个或者类似的任务吗?或者也许建议另一种实现我的目标的选择?

+0

你真的有很多专栏吗?那里有多少? –

+0

有39个值列,但列名不是静态的 –

+2

如果我正确地理解了它,为什么你不能只用“fcst_month”从表组中选择fcst_month,sum(val1 + val2 + ... + valN)?如果您向我们提供一些数据示例(输入和输出),会很好。 – Christian

回答

2

您可以逆转置使用json functionsrow_to_json()json_each_text()表。另外,使用with ordinality来获得列号。例如:

create table a_table (fcst_month int, val1 int, val2 int, val3 int); 
insert into a_table values 
(1, 10, 20, 30), 
(2, 40, 50, 60); 

select fcst_month, ordinality, key, value 
from a_table, json_each_text(row_to_json(a_table)) with ordinality; 

fcst_month | ordinality | key  | value 
------------+------------+------------+------- 
      1 |   1 | fcst_month | 1 
      1 |   2 | val1  | 10 
      1 |   3 | val2  | 20 
      1 |   4 | val3  | 30 
      2 |   1 | fcst_month | 2 
      2 |   2 | val1  | 40 
      2 |   3 | val2  | 50 
      2 |   4 | val3  | 60 
(8 rows) 

现在可以很容易地聚合值由它的位置选择列:

select fcst_month, sum(value::int) 
from a_table, json_each_text(row_to_json(a_table)) with ordinality 
where ordinality > 1 
group by 1 
order by 1; 

fcst_month | sum 
------------+----- 
      1 | 60 
      2 | 150 
(2 rows)  

个人而言,我会使用val1+ val2+ val3...即使是39列,除非我不得不处理一些动态,如未知数量的列。