2016-08-23 50 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列,除非我不得不處理一些動態,如未知數量的列。