计算Postgres(plpgsql)

时间:2016-08-23 20:52:20

标签: sql postgresql plpgsql

我有一个格式化的表:

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

我想获得每个fcst_month的所有'val'的总和。这样做的好方法似乎是使用tablefunc crosstab()(https://www.postgresql.org/docs/9.3/static/tablefunc.html)转换我的表,然后传入我的特定fcst_month的列,但是阅读文档和SO上的其他示例,I我真的不明白如何使用这个功能来实现我的目标。

有人能给我一个交叉工具()的例子来实现这个或类似的任务吗?或者或许建议另一种方法来实现我的目标?

1 个答案:

答案 0 :(得分:2)

您可以使用json functions row_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)    

除非我必须处理动态的内容,否则即使是39列,我个人也会使用val1+ val2+ val3...,例如未知数量的列。